我有一个类似
的列表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
答案 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方法速度的脚本,以及一个包含时序结果的图表:
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}]'