2013-05-14 24 views
19

Czy ktoś może polecić sposób na odwrócenie skumulowanej sumy na tablicy numpy?Wykonaj odwrotną sumę skumulowaną na tablicy numpy

Gdzie odwrotności skumulowanej sumy "jest zdefiniowany jak poniżej (Witam żadnych korekt w nazwą dla tej procedury):

razie

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

następnie

np.cumsum(x) 

daje

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

Jednak chciałbym uzyskać

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

Czy ktoś może sugerować sposób to zrobić?

Odpowiedz

34

To prawda:

np.cumsum(x[::-1])[::-1] 
+0

równoważny sposób, ale różni się składni: x [:: - 1] .cumsum() [:: - 1] – Staza

-2

Dla zabawy, za pomocą anonimowej funkcji:

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) 

Wynik:

[4, 3, 2, 1, 0] 
[0, 1, 3, 6, 10] 
[10, 10, 9, 7, 4] 
+2

FYI: 'a = np.random.randint (100, size = (1000))', '% timeit reverse_cumsum (a)': '1 pętli, najlepiej 3: 315 ms na pętlę','% timeit np.cumsum (a [:: - 1]) [:: - 1] ':' 100000 pętli, najlepiej 3: 8,89 μs na pętlę'. (Jeśli przełączę się z 'cumsum' na numpy's, to jest to' 9.75 μs na pętlę', więc wywołania funkcji nie dodają zbyt wiele narzutów, to tylko implementacja-w-python-i-wielokrotne-sumowanie- dla- nie rzeczywisty powód, który powoduje spowolnienie o 35 000 x). – Dougal

9

Tak dla przypomnienia: np.sum(x) - np.cumsum(x) jest również opcja, ale jest o połowę szybsza w przypadku dużych tablic (gdzie prędkość ma znaczenie):

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 

i mniej eleganckie, gdy chcemy zrobić cumSum wzdłuż pewnego wymiaru innego niż pierwszy:

x = np.ones((1e3,1e3)) 
np.sum(x,axis=-1)[:,np.newaxis] - np.cumsum(x,axis=-1) 
1

Można użyć .flipud() na to, jak dobrze, co jest równoznaczne z [::-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() jest nową wersją NumPy 1.12 i łączy w sobie .flipud() i .fliplr() API. https://docs.scipy.org/doc/numpy/reference/generated/numpy.flip.html

Jest to równoważne i ma mniej funkcji połączenia:

np.flip(np.flip(x, 0).cumsum(), 0)