Обобщенные кумулятивные функции в NumPy/SciPy?
Есть ли функция в numpy или scipy (или какая-то другая библиотека), которая обобщает идею cumsum и cumprod для произвольной функции. Например, рассмотрим (теоретическую) функцию
cumf( func, array)
func - это функция, которая принимает два поплавков и возвращает float. Частные случаи
lambda x,y: x+y
и
lambda x,y: x*y
- cumsum и cumprod соответственно. Например, если
func = lambda x,prev_x: x^2*prev_x
и я применяю его к:
cumf(func, np.array( 1, 2, 3) )
Я хотел бы
np.array( 1, 4, 9*4 )
Ответы
Ответ 1
NumPy ufuncs имеют accumulate()
:
In [22]: np.multiply.accumulate([[1, 2, 3], [4, 5, 6]], axis=1)
Out[22]:
array([[ 1, 2, 6],
[ 4, 20, 120]])
К сожалению, вызов accumulate()
в функции frompyfunc()
'ed Python завершается со странной ошибкой:
In [32]: uadd = np.frompyfunc(lambda x, y: x + y, 2, 1)
In [33]: uadd.accumulate([1, 2, 3])
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
ValueError: could not find a matching type for <lambda> (vectorized).accumulate,
requested type has type code 'l'
Это использует NumPy 1.6.1 с Python 2.7.3.
Ответ 2
Вышеуказанная ошибка ValueError все еще является ошибкой при использовании Numpy 1.17.2 (с Python 3.7.3).
К счастью, был найден обходной путь, который использует приведение:
https://groups.google.com/forum/#!topic/numpy/JgUltPe2hqw
import numpy as np
uadd = np.frompyfunc(lambda x, y: x + y, 2, 1)
uadd.accumulate([1,2,3], dtype=np.object).astype(np.int)
# array([1, 3, 6])
Обратите внимание, что поскольку пользовательская операция работает с np.object, она не выиграет от эффективного управления памятью numpy. Таким образом, операция может быть медленнее, чем операция, которая не нуждалась в приведении к объекту для очень больших массивов.