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: diff --git a/pandas/core/base.py b/pandas/core/base.py index 72db3cee0e80f..5bccaeef66a82 100644 --- a/pandas/core/base.py +++ b/pandas/core/base.py @@ -981,7 +981,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. @@ -1019,9 +1019,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. @@ -1041,9 +1042,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. @@ -1081,9 +1083,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. @@ -1102,6 +1105,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 e969c4b695d30..160e6284d3c59 100644 --- a/pandas/core/indexes/range.py +++ b/pandas/core/indexes/range.py @@ -327,14 +327,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 c91233e9317b7..61ab759aa8d9b 100644 --- a/pandas/tests/reductions/test_reductions.py +++ b/pandas/tests/reductions/test_reductions.py @@ -318,6 +318,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')