Ответ 1
Это делает:
np.cumsum(x[::-1])[::-1]
Может ли кто-нибудь рекомендовать способ сделать обратную суммарную сумму в массиве numpy?
Где "обратная суммарная сумма" определяется ниже (я приветствую любые исправления имени для этой процедуры):
если
x = np.array([0,1,2,3,4])
затем
np.cumsum(x)
дает
array([0,1,3,6,10])
Однако я хотел бы получить
array([10,10,9,7,4]
Может кто-нибудь предложить способ сделать это?
Это делает:
np.cumsum(x[::-1])[::-1]
Только для записи: 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)
Вы можете использовать .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)
Для удовольствия от него, используя анонимную функцию:
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]