Skip to content

Commit 2bca899

Browse files
Batalexjreback
authored andcommitted
BUG: fix numpy min/max compat with index (#26125) (#26324)
1 parent cf9ed41 commit 2bca899

File tree

4 files changed

+66
-6
lines changed

4 files changed

+66
-6
lines changed

doc/source/whatsnew/v0.25.0.rst

+1
Original file line numberDiff line numberDiff line change
@@ -433,6 +433,7 @@ Other
433433

434434
- Removed unused C functions from vendored UltraJSON implementation (:issue:`26198`)
435435
- Bug in :func:`factorize` when passing an ``ExtensionArray`` with a custom ``na_sentinel`` (:issue:`25696`).
436+
- Allow :class:`Index` and :class:`RangeIndex` to be passed to numpy ``min`` and ``max`` functions.
436437

437438

438439
.. _whatsnew_0.250.contributors:

pandas/core/base.py

+8-4
Original file line numberDiff line numberDiff line change
@@ -981,7 +981,7 @@ def _ndarray_values(self) -> np.ndarray:
981981
def empty(self):
982982
return not self.size
983983

984-
def max(self, axis=None, skipna=True):
984+
def max(self, axis=None, skipna=True, *args, **kwargs):
985985
"""
986986
Return the maximum value of the Index.
987987
@@ -1019,9 +1019,10 @@ def max(self, axis=None, skipna=True):
10191019
('b', 2)
10201020
"""
10211021
nv.validate_minmax_axis(axis)
1022+
nv.validate_max(args, kwargs)
10221023
return nanops.nanmax(self._values, skipna=skipna)
10231024

1024-
def argmax(self, axis=None, skipna=True):
1025+
def argmax(self, axis=None, skipna=True, *args, **kwargs):
10251026
"""
10261027
Return an ndarray of the maximum argument indexer.
10271028
@@ -1041,9 +1042,10 @@ def argmax(self, axis=None, skipna=True):
10411042
numpy.ndarray.argmax
10421043
"""
10431044
nv.validate_minmax_axis(axis)
1045+
nv.validate_argmax_with_skipna(skipna, args, kwargs)
10441046
return nanops.nanargmax(self._values, skipna=skipna)
10451047

1046-
def min(self, axis=None, skipna=True):
1048+
def min(self, axis=None, skipna=True, *args, **kwargs):
10471049
"""
10481050
Return the minimum value of the Index.
10491051
@@ -1081,9 +1083,10 @@ def min(self, axis=None, skipna=True):
10811083
('a', 1)
10821084
"""
10831085
nv.validate_minmax_axis(axis)
1086+
nv.validate_min(args, kwargs)
10841087
return nanops.nanmin(self._values, skipna=skipna)
10851088

1086-
def argmin(self, axis=None, skipna=True):
1089+
def argmin(self, axis=None, skipna=True, *args, **kwargs):
10871090
"""
10881091
Return a ndarray of the minimum argument indexer.
10891092
@@ -1102,6 +1105,7 @@ def argmin(self, axis=None, skipna=True):
11021105
numpy.ndarray.argmin
11031106
"""
11041107
nv.validate_minmax_axis(axis)
1108+
nv.validate_argmax_with_skipna(skipna, args, kwargs)
11051109
return nanops.nanargmin(self._values, skipna=skipna)
11061110

11071111
def tolist(self):

pandas/core/indexes/range.py

+4-2
Original file line numberDiff line numberDiff line change
@@ -327,14 +327,16 @@ def _minmax(self, meth):
327327

328328
return self._start + self._step * no_steps
329329

330-
def min(self, axis=None, skipna=True):
330+
def min(self, axis=None, skipna=True, *args, **kwargs):
331331
"""The minimum value of the RangeIndex"""
332332
nv.validate_minmax_axis(axis)
333+
nv.validate_min(args, kwargs)
333334
return self._minmax('min')
334335

335-
def max(self, axis=None, skipna=True):
336+
def max(self, axis=None, skipna=True, *args, **kwargs):
336337
"""The maximum value of the RangeIndex"""
337338
nv.validate_minmax_axis(axis)
339+
nv.validate_max(args, kwargs)
338340
return self._minmax('max')
339341

340342
def argsort(self, *args, **kwargs):

pandas/tests/reductions/test_reductions.py

+53
Original file line numberDiff line numberDiff line change
@@ -318,6 +318,59 @@ def test_minmax_nat_datetime64(self, op):
318318
obj = DatetimeIndex([pd.NaT, pd.NaT, pd.NaT])
319319
assert pd.isna(getattr(obj, op)())
320320

321+
def test_numpy_minmax_integer(self):
322+
# GH#26125
323+
idx = Index([1, 2, 3])
324+
325+
expected = idx.values.max()
326+
result = np.max(idx)
327+
assert result == expected
328+
329+
expected = idx.values.min()
330+
result = np.min(idx)
331+
assert result == expected
332+
333+
errmsg = "the 'out' parameter is not supported"
334+
with pytest.raises(ValueError, match=errmsg):
335+
np.min(idx, out=0)
336+
with pytest.raises(ValueError, match=errmsg):
337+
np.max(idx, out=0)
338+
339+
expected = idx.values.argmax()
340+
result = np.argmax(idx)
341+
assert result == expected
342+
343+
expected = idx.values.argmin()
344+
result = np.argmin(idx)
345+
assert result == expected
346+
347+
errmsg = "the 'out' parameter is not supported"
348+
with pytest.raises(ValueError, match=errmsg):
349+
np.argmin(idx, out=0)
350+
with pytest.raises(ValueError, match=errmsg):
351+
np.argmax(idx, out=0)
352+
353+
def test_numpy_minmax_range(self):
354+
# GH#26125
355+
idx = RangeIndex(0, 10, 3)
356+
357+
expected = idx._int64index.max()
358+
result = np.max(idx)
359+
assert result == expected
360+
361+
expected = idx._int64index.min()
362+
result = np.min(idx)
363+
assert result == expected
364+
365+
errmsg = "the 'out' parameter is not supported"
366+
with pytest.raises(ValueError, match=errmsg):
367+
np.min(idx, out=0)
368+
with pytest.raises(ValueError, match=errmsg):
369+
np.max(idx, out=0)
370+
371+
# No need to test again argmax/argmin compat since the implementation
372+
# is the same as basic integer index
373+
321374
def test_numpy_minmax_datetime64(self):
322375
dr = pd.date_range(start='2016-01-15', end='2016-01-20')
323376

0 commit comments

Comments
 (0)