在numpy数组上执行反向累积和

ato*_*3ls 31 python arrays numpy cumsum

任何人都可以推荐一种方法在numpy数组上进行反向累积求和吗?

其中'反向累积金额'定义如下(我欢迎对此程序的名称进行任何更正):

如果

x = np.array([0,1,2,3,4])
Run Code Online (Sandbox Code Playgroud)

然后

np.cumsum(x)
Run Code Online (Sandbox Code Playgroud)

array([0,1,3,6,10])
Run Code Online (Sandbox Code Playgroud)

但是,我想得到

array([10,10,9,7,4]
Run Code Online (Sandbox Code Playgroud)

有谁能建议这样做的方法?

ato*_*3ls 54

这样做:

np.cumsum(x[::-1])[::-1] 
Run Code Online (Sandbox Code Playgroud)

  • 一种等效的方式,但是不同的语法是:x [::-1] .cumsum()[::-1] (2认同)

Mar*_*ons 6

.flipud()也可以用于此目的,相当于[::-1] https://docs.scipy.org/doc/numpy/reference/ generated/numpy.flipud.html

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]
Run Code Online (Sandbox Code Playgroud)

.flip()从 NumPy 1.12 开始是新的,并将.flipud()和合并.fliplr()到一个 API 中。 https://docs.scipy.org/doc/numpy/reference/ generated/numpy.flip.html

这是等效的,并且函数调用更少:

np.flip(np.flip(x, 0).cumsum(), 0)
Run Code Online (Sandbox Code Playgroud)

  • 供参考。我发现对于小数组(<50 个元素),这些解决方案的速度比 np.cumsum(x[::-1])[::-1] 慢两倍。我想一定有更多的开销。谢谢。 (2认同)

Gre*_*rse 5

如果您希望将结果存储在原始数组中,那么到目前为止给出的答案似乎都是低效的。同样,如果你想要一个副本,请记住这将返回一个视图而不是一个连续的数组并且np.ascontiguousarray()仍然需要。

怎么样

view=np.flip(x, 0)
np.cumsum(view, 0, out=view)
#x contains the reverse cumsum result and remains contiguous and unflipped
Run Code Online (Sandbox Code Playgroud)

这会修改翻转视图,x它以相反的顺序将数据正确地写回原始x变量。它在执行结束时不需要非连续视图,并且速度尽可能高效。我猜 numpy 永远不会添加反向累加法,因为我描述的技术是如此简单而有效地成为可能。尽管如此,使用显式方法可能会更有效。

否则,如果需要复制,则需要额外的翻转和转换回连续数组,主要是如果它将在此后的许多向量运算中使用。numpy 的一个棘手部分,但如果您对性能非常感兴趣,则视图和连续性是需要小心的。