38

I need a fast way to keep a running maximum of a numpy array. For example, if my array was:

x = numpy.array([11,12,13,20,19,18,17,18,23,21])

I'd want:

numpy.array([11,12,13,20,20,20,20,20,23,23])

Obviously I could do this with a little loop:

def running_max(x):
    result = [x[0]]
    for val in x:
        if val > result[-1]:
            result.append(val)
        else:
            result.append(result[-1])
    return result

But my arrays have hundreds of thousands of entries and I need to call this many times. It seems like there's got to be a numpy trick to remove the loop, but I can't seem to find anything that will work. The alternative will be to write this as a C extension, but it seems like I'd be reinventing the wheel.

Alex Riley
  • 152,205
  • 43
  • 245
  • 225
Peter
  • 1,152
  • 2
  • 14
  • 15

2 Answers2

67

numpy.maximum.accumulate works for me.

>>> import numpy
>>> numpy.maximum.accumulate(numpy.array([11,12,13,20,19,18,17,18,23,21]))
array([11, 12, 13, 20, 20, 20, 20, 20, 23, 23])
Charles Beattie
  • 5,469
  • 1
  • 28
  • 32
3

As suggested, there is scipy.maximum.accumulate:

In [9]: x
Out[9]: [1, 3, 2, 5, 4]

In [10]: scipy.maximum.accumulate(x)
Out[10]: array([1, 3, 3, 5, 5])
Steve Tjoa
  • 55,811
  • 16
  • 88
  • 98
  • 6
    There is no need to get it from the scipy namespace. It's a numpy ufunc. The duplication of the numpy symbols in scipy.* is a backwards-compatibility leftover from the days of Numeric. – Robert Kern Aug 31 '11 at 02:14
  • Sorry about that. Personal bias, I guess. – Steve Tjoa Aug 31 '11 at 22:24