Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Perform a reverse cumulative sum on a numpy array

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?

like image 928
atomh33ls Avatar asked May 14 '13 11:05

atomh33ls


People also ask

How do I reverse the order of a NumPy array?

The flip() method is used to reverse the order of values in an array along the given axis. The flip() method is defined under the numpy library, which can be imported as import numpy as np, and we can create multidimensional arrays and create other mathematical statistics with the help of the Python numpy module.

How do I reverse the order of rows in NumPy?

An array object in NumPy is called ndarray, which is created using the array() function. To reverse column order in a matrix, we make use of the numpy. fliplr() method. The method flips the entries in each row in the left/right direction.


3 Answers

This does it:

np.cumsum(x[::-1])[::-1] 
like image 67
atomh33ls Avatar answered Oct 19 '22 00:10

atomh33ls


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)
like image 34
Marc Gibbons Avatar answered Oct 19 '22 00:10

Marc Gibbons


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.

like image 25
Gregory Morse Avatar answered Oct 18 '22 22:10

Gregory Morse