Cam.Davidson.Pilon
Cam.Davidson.Pilon

Reputation: 1726

generalized cumulative functions in NumPy/SciPy?

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 )

Upvotes: 20

Views: 4756

Answers (2)

user2561747
user2561747

Reputation: 1394

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.

Upvotes: 15

NPE
NPE

Reputation: 500663

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.

Upvotes: 13

Related Questions