Perform a reverse cumulative sum on a numpy array
Asked Answered
M

3

43

Can anyone recommend a way to do a reverse cumulative sum on a numpy array?

Where 'reverse cumulative sum' is defined as below (I welcome any corrections on the name for this procedure):

if

x = np.array([0,1,2,3,4])

then

np.cumsum(x)

gives

array([0,1,3,6,10])

However, I would like to get

array([10,10,9,7,4]

Can anyone suggest a way to do this?

Michaels answered 14/5, 2013 at 11:8 Comment(0)
M
71

This does it:

np.cumsum(x[::-1])[::-1] 
Michaels answered 14/5, 2013 at 11:14 Comment(2)
An equivalent way, but different syntax is: x[::-1].cumsum()[::-1]Infamy
For anyone who wants to know, for multidimensional arrays you just need to hold any rows/columns constant i.e if x is a two dimensional array then np.cumsum(x[:, ::-1], axis=1)[:, ::-1] sums along the rows in reverse.Mckinnie
D
7

You can use .flipud() for this as well, which is equivalent to [::-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]

.flip() is new as of NumPy 1.12, and combines the .flipud() and .fliplr() into one API. https://docs.scipy.org/doc/numpy/reference/generated/numpy.flip.html

This is equivalent, and has fewer function calls:

np.flip(np.flip(x, 0).cumsum(), 0)
Detrition answered 31/3, 2017 at 13:30 Comment(1)
FYI. I found these solutions twice as slow as np.cumsum(x[::-1])[::-1] for small arrays (<50 elements). There must be more overhead I suppose. Thanks.Croton
S
7

The answers given so far seem to be all inefficient if you want the result stored in the original array. As well, if you want a copy, keep in mind this will return a view not a contiguous array and np.ascontiguousarray() is still needed.

How about

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

This modifies the flipped view of x which writes the data properly in reverse order back into the original x variable. It requires no non-contiguous views at the end of execution and is about as speed efficient as possible. I am guessing numpy will never add a reversecumsum method namely because the technique I describe is so trivially and efficiently possible. Albeit, it might be ever so slightly more efficient to have the explicit method.

Otherwise if a copy is desired, then the extra flip is required AND conversion back to a contiguous array, mainly if it will be used in many vector operations thereafter. A tricky part of numpy, but views and contiguity are something to be careful with if you are seriously interested in performance.

Solemnity answered 25/11, 2019 at 0:51 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.