【问题标题】:How to maintain a cumulative sum?如何保持累计金额?
【发布时间】:2017-09-28 18:38:12
【问题描述】:

我有一个sorteddict,我对这些值的累积总和感兴趣:

>>> from blist import sorteddict
>>> import numpy as np
>>> x = sorteddict({1:1, 2:2, 5:5})
>>> zip(x.keys(), np.cumsum(x.values())) 
[(1, 1), (2, 3), (5, 8)]

但是,我经常需要更新字典,因此需要重新计算累积和:

>>> x[4] = 4
>>> zip(x.keys(), np.cumsum(x.values()))
[(1, 1), (2, 3), (4, 7), (5, 12)]

>>> x[3] = 3
>>> zip(x.keys(), np.cumsum(x.values()))
[(1, 1), (2, 3), (3, 6), (4, 10), (5, 15)]

我想知道是否有一些巧妙的方法可以有效地保持累积和,而不是不断地重新计算累积和?

注意

>>> import sys
>>> sys.version
'2.7.11 (default, Jun 15 2016, 17:53:20) [MSC v.1800 32 bit (Intel)]'

一般来说,我的键和值也不一样——我只是在我的例子中很懒

【问题讨论】:

  • 钥匙是数字吗? sorteddict 是必须的吗?您对插入有什么复杂性要求?
  • @kabanus 键是数字。 sorteddict 不是必须的,但我的数据以(键,值)对的形式出现,并且值的累积和应根据键的顺序执行。我唯一的要求是时间复杂度应该小于不断地重新计算累积和。
  • 你需要这些钱做什么?是必须立即更新,还是按需更新?您最终需要将更改传播到上游,因此用例在这里很重要 - 我猜您在请求总和时需要 O(1)。
  • @kabanus 每次更新后我都需要它。通常我只需要更新一个(键,值)对,但有时我需要更新一小批(键,值)对。当我批量更新时,我只需要整个批次写入后的累积总和。
  • 那么这是一个难题——您既要立即插入又要立即计算。我认为你可能不得不放弃一点——要么减慢插入速度,要么减慢总和的访问速度。无论如何,一个小的优化是自己维护字典,并在插入期间仅在上游添加累积总和。假设平均插入/更改是从中间开始,这将减少一半的时间。

标签: python cumulative-sum sorteddictionary


【解决方案1】:

这个怎么样:

import collections

def add_and_regenerate_sums(term, master):
    index, value = term
    master[index] = value
    master = collections.OrderedDict(sorted(master.items(), key=lambda z: z[0]))
    y = dict()
    sum_of = 0
    for i, j in master.items():
        sum_of += j
        y[i] = sum_of

    return dict(sorted(y.items(), key=lambda z: z[0])), master

x = collections.OrderedDict({1:1, 2:2, 5:5})

sums, master = add_and_regenerate_sums((3, 10), x)
print(sums)
print(master)

然后您可以根据加法得到总和以及稍后操作的新字典。

【讨论】:

    猜你喜欢
    • 2017-08-01
    • 1970-01-01
    • 2016-03-27
    • 1970-01-01
    • 1970-01-01
    • 2022-10-25
    • 2023-03-15
    • 2021-03-16
    • 1970-01-01
    相关资源
    最近更新 更多