Moormanly
Moormanly

Reputation: 1438

Is there a function like `cumreduce` along the lines of `numpy.cumsum` or `numpy.cumprod` in python?

When I need the sum or product of the elements in a list such as

>>> foo = [10, 5, 3, 4]

I can use the sum or prod functions of numpy

>>> import numpy as np

>>> np.sum(foo)
22

>>> np.prod(foo)
600

Likewise, when I need the cumulative sum or product, I can use np.cumsum or np.cumprod

>>> np.cumsum(foo)
array([10, 15, 18, 22])

>>> np.cumprod(foo)
array([ 10,  50, 150, 600])

Is there a way I can obtain the cumulative result of an arbitrary reduce operation?


For example, if I had a function like

def my_fn(a, b):
    return a + b**2

I could use functools.reduce to obtain

>>> from functools import reduce
>>> reduce(my_fn, foo)
60

What I am looking for is a function which would give me the following

>>> cumreduce(my_fn, foo)
[10, 35, 44, 60]

That is, each element of the result is equal to reduce(my_fn, foo[:i]).


Of course, I can do this in the naive way

>>> def cumreduce(fn, seq):
...     return [reduce(fn, seq[:i]) for i in range(1, len(seq)+1)]

>>> cumreduce(my_fn, foo)
[10, 35, 44, 60]

Ideally I am looking for a built-in function with the same or similar functionality.

Upvotes: 1

Views: 319

Answers (1)

Paul Panzer
Paul Panzer

Reputation: 53079

In Python, what you are looking for is itertools.accumulate:

import itertools

[*itertools.accumulate(foo,my_fn)]
# [10, 35, 44, 60]

Numpy ufuncs often have an accumulate method. Examples:

np.bitwise_xor.accumulate(foo)
array([10, 15, 12,  8])

np.add.accumulate(foo)
array([10, 15, 18, 22])
# cf. cumsum:
np.cumsum(foo)
array([10, 15, 18, 22]

Upvotes: 2

Related Questions