Подтвердить что ты не робот

Выполните обратную суммарную сумму на массив numpy

Может ли кто-нибудь рекомендовать способ сделать обратную суммарную сумму в массиве numpy?

Где "обратная суммарная сумма" определяется ниже (я приветствую любые исправления имени для этой процедуры):

если

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

затем

np.cumsum(x)

дает

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

Однако я хотел бы получить

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

Может кто-нибудь предложить способ сделать это?

4b9b3361

Ответ 1

Это делает:

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

Ответ 2

Только для записи: 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)

Ответ 3

Вы можете использовать .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]

.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)

Ответ 4

Для удовольствия от него, используя анонимную функцию:

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]