Pregunta

Is there a function in numpy or scipy (or some other library) that generalizes the idea of cumsum and cumprod to arbitrary function. For example, consider the (theoretical) function

cumf( func, array) 

func is a function that accepts two floats, and returns a float. Particular cases

lambda x,y: x+y 

and

lambda x,y: x*y 

are cumsum and cumprod respectively. For example, if

func = lambda x,prev_x: x^2*prev_x 

and I apply it to:

cumf(func, np.array( 1, 2, 3) )

I would like

np.array( 1, 4, 9*4 )
¿Fue útil?

Solución 2

NumPy's ufuncs have accumulate():

In [22]: np.multiply.accumulate([[1, 2, 3], [4, 5, 6]], axis=1)
Out[22]: 
array([[  1,   2,   6],
       [  4,  20, 120]])

Unfortunately, calling accumulate() on a frompyfunc()'ed Python function fails with a strange error:

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'

This is using NumPy 1.6.1 with Python 2.7.3.

Otros consejos

The ValueError above is still a bug using Numpy 1.20.1 (with Python 3.9.1).

Luckily a workaround was discovered that uses casting: 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=object).astype(int)
# array([1, 3, 6])

Note that since the custom operation works on an object type, it won't benefit from the efficient memory management of numpy. So the operation may be slower than one that didn't need casting to object for extremely large arrays.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top