Rolling min of a Pandas Series without window / cumulative minimum / expanding min

Viewed 246

I'm looking for a way to calculate with Python Pandas rolling(*) min of a Series without window.

Let's consider the following Series

In [26]: s = pd.Series([10, 12, 14, 9, 10, 8, 16, 20])
Out[26]:
0    10
1    12
2    14
3     9
4    10
5     8
6    16
7    20
dtype: int64

I would like to get a Series like

0    10
1    10
2    10
3     9
4     9
5     8
6     8
7     8
dtype: int64

I tried

s.rolling().min()

but I'm getting the following error

TypeError: rolling() missing 1 required positional argument: 'window'

I did this

r = s.copy()
val_min = r.iloc[0]
for i, (idx, val) in enumerate(r.iteritems()):
    if i > 0:
        if val < val_min:
            val_min = val
        else:
            r[idx] = val_min

and have a correct answer

In [30]: r
Out[30]:
0    10
1    10
2    10
3     9
4     9
5     8
6     8
7     8
dtype: int64

but I think a Pandas method should probably exist (and be much more efficient) or if it doesn't exist, it should probably be implemented.

(*) "rolling" may not be the appropriate term, maybe it should be named instead a "local" min.

Edit: it's in fact named a cumulative minimum or expanding min

3 Answers

Use Series.cummin:

print(s.cummin())
0    10
1    10
2    10
3     9
4     9
5     8
6     8
7     8
dtype: int64

You can use np.minimum.accumulate:

import numpy as np

pd.Series(np.minimum.accumulate(s.values))

0    10
1    10
2    10
3     9
4     9
5     8
6     8
7     8
dtype: int64

Another way is to use s.expanding.min (see Series.expanding):

s.expanding().min()

Output:

0    10.0
1    10.0
2    10.0
3     9.0
4     9.0
5     8.0
6     8.0
7     8.0
Related