wesm/pandas — Issue #647: request: new functions cummax, cummin
Author: fabriziop
Created: 2012-01-18 16:39:50+00:00
State: open

I have found useful cummax and cummin functions in R, so I propose to add them to pandas. I enclose belove an imple-mentation dumbly derived from the cumsum function.

File /pandas/core/series.py , Series class, methods to be added.

```
def cummax(self, axis=0, dtype=None, out=None, skipna=True):
"""
Cumulative max of values. Preserves locations of NaN values

Extra parameters are to preserve ndarray interface.

Parameters
----------
skipna : boolean, default True
Exclude NA/null values

Returns
-------
cummax : Series
"""
arr = self.values.copy()

do_mask = skipna and not issubclass(self.dtype.type, np.integer)
if do_mask:
mask = isnull(arr)
np.putmask(arr, mask, -np.inf)

result = np.maximum.accumulate(arr)

if do_mask:
np.putmask(result, mask, np.nan)

return Series(result, index=self.index)

def cummin(self, axis=0, dtype=None, out=None, skipna=True):
"""
Cumulative min of values. Preserves locations of NaN values

Extra parameters are to preserve ndarray interface.

Parameters
----------
skipna : boolean, default True
Exclude NA/null values

Returns
-------
cummin : Series
"""
arr = self.values.copy()

do_mask = skipna and not issubclass(self.dtype.type, np.integer)
if do_mask:
mask = isnull(arr)
np.putmask(arr, mask, np.inf)

result = np.minimum.accumulate(arr)

if do_mask:
np.putmask(result, mask, np.nan)

return Series(result, index=self.index)
```

File pandas/core/generic.py, NDFrame class, methods to be added

```
def cummax(self, axis=None, skipna=True):
"""
Return DataFrame of cumulative max over requested axis.

Parameters
----------
axis : {0, 1}
0 for row-wise, 1 for column-wise
skipna : boolean, default True
Exclude NA/null values. If an entire row/column is NA, the result
will be NA

Returns
-------
y : DataFrame
"""
if axis is None:
axis = self._default_stat_axis
else:
axis = self._get_axis_number(axis)

y = self.values.copy()
if not issubclass(y.dtype.type, np.integer):
mask = np.isnan(self.values)

if skipna:
np.putmask(y, mask, -np.inf)

result = np.maximum.accumulate(y,axis)

if skipna:
np.putmask(result, mask, np.nan)
else:
result = np.maximum.accumulate(y,axis)
return self._wrap_array(result, self.axes, copy=False)

def cummin(self, axis=None, skipna=True):
"""
Return DataFrame of cumulative min over requested axis.

Parameters
----------
axis : {0, 1}
0 for row-wise, 1 for column-wise
skipna : boolean, default True
Exclude NA/null values. If an entire row/column is NA, the result
will be NA

Returns
-------
y : DataFrame
"""
if axis is None:
axis = self._default_stat_axis
else:
axis = self._get_axis_number(axis)

y = self.values.copy()
if not issubclass(y.dtype.type, np.integer):
mask = np.isnan(self.values)

if skipna:
np.putmask(y, mask, np.inf)

result = np.minimum.accumulate(y,axis)

if skipna:
np.putmask(result, mask, np.nan)
else:
result = np.minimum.accumulate(y,axis)
return self._wrap_array(result, self.axes, copy=False)
```