From 66fa067e4bbec393bb7ebcb52a37c36d0d24472c Mon Sep 17 00:00:00 2001 From: Alexandre Batisse Date: Thu, 9 May 2019 10:32:14 +0200 Subject: [PATCH 1/2] BUG: fix numpy min/max compat with integer index (#26125) --- pandas/core/base.py | 12 +++-- pandas/core/indexes/range.py | 6 ++- pandas/tests/reductions/test_reductions.py | 53 ++++++++++++++++++++++ 3 files changed, 65 insertions(+), 6 deletions(-) diff --git a/pandas/core/base.py b/pandas/core/base.py index de2989e851e04..cddabb655163b 100644 --- a/pandas/core/base.py +++ b/pandas/core/base.py @@ -966,7 +966,7 @@ def _ndarray_values(self) -> np.ndarray: def empty(self): return not self.size - def max(self, axis=None, skipna=True): + def max(self, axis=None, skipna=True, *args, **kwargs): """ Return the maximum value of the Index. @@ -1004,9 +1004,10 @@ def max(self, axis=None, skipna=True): ('b', 2) """ nv.validate_minmax_axis(axis) + nv.validate_max(args, kwargs) return nanops.nanmax(self._values, skipna=skipna) - def argmax(self, axis=None, skipna=True): + def argmax(self, axis=None, skipna=True, *args, **kwargs): """ Return an ndarray of the maximum argument indexer. @@ -1021,9 +1022,10 @@ def argmax(self, axis=None, skipna=True): numpy.ndarray.argmax """ nv.validate_minmax_axis(axis) + nv.validate_argmax_with_skipna(skipna, args, kwargs) return nanops.nanargmax(self._values, skipna=skipna) - def min(self, axis=None, skipna=True): + def min(self, axis=None, skipna=True, *args, **kwargs): """ Return the minimum value of the Index. @@ -1061,9 +1063,10 @@ def min(self, axis=None, skipna=True): ('a', 1) """ nv.validate_minmax_axis(axis) + nv.validate_min(args, kwargs) return nanops.nanmin(self._values, skipna=skipna) - def argmin(self, axis=None, skipna=True): + def argmin(self, axis=None, skipna=True, *args, **kwargs): """ Return a ndarray of the minimum argument indexer. @@ -1082,6 +1085,7 @@ def argmin(self, axis=None, skipna=True): numpy.ndarray.argmin """ nv.validate_minmax_axis(axis) + nv.validate_argmax_with_skipna(skipna, args, kwargs) return nanops.nanargmin(self._values, skipna=skipna) def tolist(self): diff --git a/pandas/core/indexes/range.py b/pandas/core/indexes/range.py index cd31fdeca03ab..b65563c8f6573 100644 --- a/pandas/core/indexes/range.py +++ b/pandas/core/indexes/range.py @@ -322,14 +322,16 @@ def _minmax(self, meth): return self._start + self._step * no_steps - def min(self, axis=None, skipna=True): + def min(self, axis=None, skipna=True, *args, **kwargs): """The minimum value of the RangeIndex""" nv.validate_minmax_axis(axis) + nv.validate_min(args, kwargs) return self._minmax('min') - def max(self, axis=None, skipna=True): + def max(self, axis=None, skipna=True, *args, **kwargs): """The maximum value of the RangeIndex""" nv.validate_minmax_axis(axis) + nv.validate_max(args, kwargs) return self._minmax('max') def argsort(self, *args, **kwargs): diff --git a/pandas/tests/reductions/test_reductions.py b/pandas/tests/reductions/test_reductions.py index eae940e8ee0ee..a82791a71b6b2 100644 --- a/pandas/tests/reductions/test_reductions.py +++ b/pandas/tests/reductions/test_reductions.py @@ -319,6 +319,59 @@ def test_minmax_nat_datetime64(self, op): obj = DatetimeIndex([pd.NaT, pd.NaT, pd.NaT]) assert pd.isna(getattr(obj, op)()) + def test_numpy_minmax_integer(self): + # GH#26125 + idx = Index([1, 2, 3]) + + expected = idx.values.max() + result = np.max(idx) + assert result == expected + + expected = idx.values.min() + result = np.min(idx) + assert result == expected + + errmsg = "the 'out' parameter is not supported" + with pytest.raises(ValueError, match=errmsg): + np.min(idx, out=0) + with pytest.raises(ValueError, match=errmsg): + np.max(idx, out=0) + + expected = idx.values.argmax() + result = np.argmax(idx) + assert result == expected + + expected = idx.values.argmin() + result = np.argmin(idx) + assert result == expected + + errmsg = "the 'out' parameter is not supported" + with pytest.raises(ValueError, match=errmsg): + np.argmin(idx, out=0) + with pytest.raises(ValueError, match=errmsg): + np.argmax(idx, out=0) + + def test_numpy_minmax_range(self): + # GH#26125 + idx = RangeIndex(0, 10, 3) + + expected = idx._int64index.max() + result = np.max(idx) + assert result == expected + + expected = idx._int64index.min() + result = np.min(idx) + assert result == expected + + errmsg = "the 'out' parameter is not supported" + with pytest.raises(ValueError, match=errmsg): + np.min(idx, out=0) + with pytest.raises(ValueError, match=errmsg): + np.max(idx, out=0) + + # No need to test again argmax/argmin compat since the implementation + # is the same as basic integer index + def test_numpy_minmax_datetime64(self): dr = pd.date_range(start='2016-01-15', end='2016-01-20') From 4f1eecd1f2bdeebf0e2adf86347d820bbbbdb8a2 Mon Sep 17 00:00:00 2001 From: Alexandre Batisse Date: Thu, 9 May 2019 10:44:01 +0200 Subject: [PATCH 2/2] add whatsnew entry --- doc/source/whatsnew/v0.25.0.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/source/whatsnew/v0.25.0.rst b/doc/source/whatsnew/v0.25.0.rst index 578e24009d35a..e0b4baf5d8543 100644 --- a/doc/source/whatsnew/v0.25.0.rst +++ b/doc/source/whatsnew/v0.25.0.rst @@ -433,6 +433,7 @@ Other - Removed unused C functions from vendored UltraJSON implementation (:issue:`26198`) - Bug in :func:`factorize` when passing an ``ExtensionArray`` with a custom ``na_sentinel`` (:issue:`25696`). +- Allow :class:`Index` and :class:`RangeIndex` to be passed to numpy ``min`` and ``max`` functions. .. _whatsnew_0.250.contributors: