如何在python中查找字典列表中的累计项目总和

时间:2016-08-20 12:56:49

标签: python pandas numpy dictionary deque

我有一个类似

的列表
a=[{'time':3},{'time':4},{'time':5}]

我希望以相反的顺序得到值的累积总和,如此

b=[{'exp':3,'cumsum':12},{'exp':4,'cumsum':9},{'exp':5,'cumsum':5}]

最有效的方法是什么?我已经阅读了其他答案,其中使用numpy给出了像

这样的解决方案
a=[1,2,3]
b=numpy.cumsum(a)

但我也需要在字典中插入cumsum

6 个答案:

答案 0 :(得分:7)

for i in 0x21...0x100 {
    print(UnicodeScalar(i), terminator: "")
}

<强>输出:

a=[{'time':3},{'time':4},{'time':5}]
b = []
cumsum = 0
for e in a[::-1]:
    cumsum += e['time']
    b.insert(0, {'exp':e['time'], 'cumsum':cumsum})
print(b)

<小时/> 事实证明,在列表的开头插入是slow(O(n))。相反,请尝试[{'exp': 3, 'cumsum': 12}, {'exp': 4, 'cumsum': 9}, {'exp': 5, 'cumsum': 5}] (O(1)):

deque

<强>输出:

from collections import deque


a=[{'time':3},{'time':4},{'time':5}]
b = deque()
cumsum = 0
for e in a[::-1]:
    cumsum += e['time']
    b.appendleft({'exp':e['time'], 'cumsum':cumsum})
print(b)
print(list(b))

<小时/> 这是一个测试每个ITT方法速度的脚本,以及一个包含时序结果的图表:

enter image description here

deque([{'cumsum': 12, 'exp': 3}, {'cumsum': 9, 'exp': 4}, {'cumsum': 5, 'exp': 5}])
[{'cumsum': 12, 'exp': 3}, {'cumsum': 9, 'exp': 4}, {'cumsum': 5, 'exp': 5}]

答案 1 :(得分:2)

基于生成器的解决方案:

def foo(a, var='value'):
    cum=0
    for i in a:
        j=i[var]
        cum += j
        yield {var:j, 'sum':cum}

In [79]: a=[{'time':i} for i in range(5)]
In [80]: list(foo(a[::-1], var='time'))[::-1]
Out[80]: 
[{'sum': 10, 'time': 0},
 {'sum': 10, 'time': 1},
 {'sum': 9, 'time': 2},
 {'sum': 7, 'time': 3},
 {'sum': 4, 'time': 4}]

在快速时间测试中,这与cb_insert_0

相比具有竞争力

就地版本的确做得更好:

def foo2(a, var='time'):
    cum = 0
    for i in a:
        cum += i[var]
        i['sum'] = cum
foo2(a[::-1])

答案 2 :(得分:1)

试试这个,

cumsum_list = np.cumsum([i['time'] for i in a][::-1])[::-1]
for i,j in zip(a,cumsum_list):
     i.update({'cumsum':j})

<强>结果

[{'cumsum': 12, 'time': 3}, {'cumsum': 9, 'time': 4}, {'cumsum': 5, 'time': 5}]

<强>效率

转换为函数,

In [49]: def convert_dict(a):
....:     cumsum_list = np.cumsum([i['time'] for i in a][::-1])[::-1]
....:     for i,j in zip(a,cumsum_list):
....:              i.update({'cumsum':j})
....:     return a

然后是结果,

In [51]: convert_dict(a)
Out[51]: [{'cumsum': 12, 'time': 3}, {'cumsum': 9, 'time': 4}, {'cumsum': 5, 'time': 5}]

最后效率,

In [52]: %timeit convert_dict(a)
The slowest run took 12.84 times longer than the fastest. This could mean that an intermediate result is being cached.
100000 loops, best of 3: 12.1 µs per loop

答案 3 :(得分:1)

这是使用pandas -

的另一种方法
df = pd.DataFrame(a)
df.columns = ['exp']
df['cumsum'] = (df[::-1].cumsum())[::-1]
out = df.T.to_dict().values()

示例输入,输出 -

In [396]: a
Out[396]: [{'time': 3}, {'time': 4}, {'time': 5}]

In [397]: out
Out[397]: [{'cumsum': 12, 'exp': 3}, {'cumsum': 9, 'exp': 4}, {'cumsum': 5, 'exp': 5}

答案 4 :(得分:1)

试试这个:

a            = [{'time':3},{'time':4},{'time':5}]
df           = pd.DataFrame(a).rename(columns={'time':'exp'})
df["cumsum"] = df['exp'][::-1].cumsum()
df.to_dict(orient='records')

没有订购Dicts。

 [{'cumsum': 12, 'exp': 3}, {'cumsum': 9, 'exp': 4}, {'cumsum': 5, 'exp': 5}]

答案 5 :(得分:0)

使用pandas

In [4]: df = pd.DataFrame([{'time':3},{'time':4},{'time':5}])

In [5]: df
Out[5]: 
   time
0     3
1     4
2     5

In [6]: df['cumsum'] = df.ix[::-1, 'time'].cumsum()[::-1]

In [7]: df
Out[7]: 
   time  cumsum
0     3      12
1     4       9
2     5       5

In [8]: df.columns = ['exp', 'cumsum']

In [9]: df
Out[9]: 
   exp  cumsum
0    3      12
1    4       9
2    5       5

In [10]: df.to_json(orient='records')
Out[10]: '[{"exp":3,"cumsum":12},{"exp":4,"cumsum":9},{"exp":5,"cumsum":5}]'