有人可以推荐一种方法在numpy数组上进行反向累积求和吗?
其中'反向累积金额'定义如下(我欢迎对此程序的名称进行任何更正):
如果
x = np.array([0,1,2,3,4])
然后
np.cumsum(x)
给出
array([0,1,3,6,10])
但是,我想得到
array([10,10,9,7,4]
有人可以建议这样做吗?
答案 0 :(得分:46)
这样做:
np.cumsum(x[::-1])[::-1]
答案 1 :(得分:9)
仅供记录:np.sum(x) - np.cumsum(x)
也是一个选项,但在大型阵列上速度快一半(速度很重要):
In [8]: x = np.ones(1e8)
In [9]: %timeit np.cumsum(x[::-1])[::-1]
1 loops, best of 3: 547 ms per loop
In [10]: %timeit np.sum(x) - np.cumsum(x)
1 loops, best of 3: 974 ms per loop
并且想要沿着第一个以外的某个维度做一个cumsum时不那么优雅:
x = np.ones((1e3,1e3))
np.sum(x,axis=-1)[:,np.newaxis] - np.cumsum(x,axis=-1)
答案 2 :(得分:2)
您也可以使用In [0]: x = np.array([0,1,2,3,4])
In [1]: np.flipud(np.flipud(x).cumsum())
Out[1]: array([10, 10, 9, 7, 4]
,这相当于.flip()
https://docs.scipy.org/doc/numpy/reference/generated/numpy.flipud.html
.flipud()
.fliplr()
是NumPy 1.12的新功能,它将np.flip(np.flip(x, 0).cumsum(), 0)
和nothing
合并为一个API。
https://docs.scipy.org/doc/numpy/reference/generated/numpy.flip.html
这是等效的,并且函数调用次数较少:
using NIfTI # Julia package for reading NIfTI medical images
type RR
source::Union(NIfTI.NIVolume, nothing)
end
答案 3 :(得分:0)
如果您想将结果存储在原始数组中,那么到目前为止给出的答案似乎都是无效的。同样,如果您想要一个副本,请记住,这将返回一个非连续数组的视图,并且仍然需要np.tocontiguousarray()。
怎么样
view=np.flip(x, 0)
np.cumsum(view, 0, out=view)
#x contains the reverse cumsum result and remains contiguous and unflipped
这将修改x
的翻转视图,该视图以相反的顺序将数据正确地写回到原始x
变量中。它在执行结束时不需要非连续视图,并且尽可能地提高速度效率。我猜想numpy永远不会添加反向求和方法,因为我描述的技术是如此简单有效。但是,使用显式方法可能会稍微更有效。
否则,如果需要复制,则需要额外的翻转并将其转换回连续数组,主要是如果此后它将在许多矢量操作中使用它。 numpy的一个棘手的部分,但是如果您对性能非常感兴趣,则必须谨慎对待视图和连续性。
答案 4 :(得分:-2)
为了好玩,使用匿名函数:
array = [0,1,2,3,4]
reverse = lambda a: a[::-1]
cumsum = lambda a: [ sum(a[:i+1]) for i,x in enumerate(a) ] # there is also an accumulate function present in the itertools module
print reverse(array)
print cumsum(array)
# sadly, no compose function in Python
reverse_cumsum = lambda a: reverse( cumsum ( reverse(a) ) )
print reverse_cumsum(array)
结果:
[4, 3, 2, 1, 0]
[0, 1, 3, 6, 10]
[10, 10, 9, 7, 4]