说我有清单,list_a = [100, 5, 1, 2, 200, 3, 1, 300, 6, 6]
还有另一个列表,ind_list = [0, 4, 7]
我想创建第三个列表,其中包含第一个列表的累积总和,该列表“重设”来自ind_list
的每个索引。
为澄清起见,结果应为res_list = [100, 105, 106, 108, 200, 203, 204, 300, 306, 312]
答案 0 :(得分:9)
使用以下内容:
cs= np.cumsum(list_a)
for i in ind_list:
if i==0:
continue
cs[i:]-=cs[i-1]
结果:
cs
>>array([100, 105, 106, 108, 200, 203, 204, 300, 306, 312])
答案 1 :(得分:4)
有itertools
人需要救援:
from itertools import accumulate as acc, chain
list_a = [100, 5, 1, 2, 200, 3, 1, 300, 6, 6]
ind_list = [0, 4, 7]
list(chain(*(acc(list_a[x:y]) for x, y in zip(ind_list, ind_list[1:]+[None]))))
# [100, 105, 106, 108, 200, 203, 204, 300, 306, 312]
答案 2 :(得分:3)
它是NumPy标记的,找到矢量化解决方案很有趣,所以这里是一个-
def intervaled_cumsum(list_a, ind_list):
a = np.array(list_a)
a[ind_list[1:]] -= np.add.reduceat(a,ind_list)[:-1]
return a.cumsum()
样品运行-
In [54]: list_a = [100, 5, 1, 2, 200, 3, 1, 300, 6, 6]
In [55]: ind_list = [0, 4, 7]
In [56]: intervaled_cumsum(list_a, ind_list)
Out[56]: array([100, 105, 106, 108, 200, 203, 204, 300, 306, 312])
答案 3 :(得分:2)
或者只是创建一个生成器:
def generate_running_sum(summands, index_list):
current_sum = 0
for i, summand in enumerate(summands):
if i in set(index_list):
current_sum = 0
current_sum += summand
yield current_sum
应用于您的数据:
list_a = [100, 5, 1, 2, 200, 3, 1, 300, 6, 6]
ind_list = [0, 4, 7]
res_list = list(generate_running_sum(summands=list_a, index_list=ind_list))
print(res_list)
答案 4 :(得分:1)
我通过zip
和np.cumsum
的组合来做到这一点。
我考虑了[0-4)
,[4-7)
和[7-(len(list)))
的索引。
然后我找到列表中每个切片的累积总和,然后将其放在另一个列表中:
import numpy as np
list_a = [100, 5, 1, 2, 200, 3, 1, 300, 6, 6]
ind_list = [0, 4, 7]
def createcumsum(list_a, ind_list):
# For adding the end of the list to the indexes if it doesn't exist
if ind_list[-1] != len(list_a):
ind_list.append(len(list_a))
res_list=[]
# Considers the indexes from 0-4, 4-7, 7-(endoflist)
for x,y in zip(ind_list, ind_list[1:]):
# Take cumulativesum on the above mentioned slices
res_list.extend(np.cumsum(list_a[x:y]))
return res_list
print(createcumsum(list_a, ind_list))
[100, 105, 106, 108, 200, 203, 204, 300, 306, 312]
答案 5 :(得分:1)
最大itertools
次滥用!
设置
from itertools import accumulate, chain, islice, tee
def pairwise(iterable):
'pairwise recipe from itertools docs'
it1, it2 = tee(iterable)
next(it2)
return zip(it1, it2)
list_a = [100, 5, 1, 2, 200, 3, 1, 300, 6, 6]
ind_list = [0, 4, 7]
解决方案
ind_list.append(None)
result = list(chain.from_iterable(accumulate(islice(list_a, start, stop))
for start, stop in pairwise(ind_list)))
print(result)
输出
[100, 105, 106, 108, 200, 203, 204, 300, 306, 312]
在这里尽可能使用itertools
工具的想法是避免创建不必要地占用内存的中间列表切片。
〜编辑~~
高效内存的Python 2.7解决方案
from itertools import chain, islice, izip, tee
def pairwise(iterable):
'pairwise recipe from itertools docs'
it1, it2 = tee(iterable)
next(it2)
return izip(it1, it2)
def my_cumsum(iterable):
s = 0
for x in iterable:
s += x
yield s
list_a = [100, 5, 1, 2, 200, 3, 1, 300, 6, 6]
ind_list = [0, 4, 7]
ind_list.append(None)
result = list(chain.from_iterable(my_cumsum(islice(list_a, start, stop))
for start, stop in pairwise(ind_list)))
print(result)
答案 6 :(得分:1)
我必须手动扩展ind_list:
ind_list = [0, 4, 7] + [len(list_a)]
只需运行一个嵌套循环,并将嵌套范围设置为上述ind_list:
count, final = 0, []
for i in range(len(ind_list)-1):
count = 0
for i in range(ind_list[i],ind_list[i+1]):
count += list_a[i]
final.append(count)
答案 7 :(得分:1)
仅使用NumPy的答案稍微简单些:
import numpy as np
list_a = [100, 5, 1, 2, 200, 3, 1, 300, 6, 6]
ind_list = [2, 4, 7]
res_list = []
for i, n in enumerate(ind_list):
if i == 0:
n_prev=0
else:
n_prev = ind_list[i-1]
for k in range(n-n_prev):
res_list.append(np.sum(list_a[n_prev:n_prev+k+1]))
if i == len(ind_list)-1:
for k in range(len(list_a)-n):
res_list.append(np.sum(list_a[n:n+k+1]))
print(res_list)
[100, 105, 106, 108, 200, 203, 204, 300, 306, 312]