Skip to content

Commit 9fab462

Browse files
committed
Deprecate numeric_only parameter in Categorical.min and max
1 parent af498fe commit 9fab462

File tree

5 files changed

+50
-42
lines changed

5 files changed

+50
-42
lines changed

doc/source/whatsnew/v0.25.1.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,11 @@ For example, on MacOS installing Python with `pyenv` may lead to an incomplete P
1616

1717
.. _whatsnew_0251.bug_fixes:
1818

19+
Other deprecations
20+
^^^^^^^^^^^^^^^^^^
21+
22+
- The parameter ``numeric_only`` of :meth:`Categorical.min` and :meth:`Categorical.max` is deprecated and replaced with ``skipna`` (:issue:`25303`)
23+
1924
Bug fixes
2025
~~~~~~~~~
2126

pandas/core/arrays/categorical.py

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2196,7 +2196,8 @@ def _reduce(self, name, axis=0, **kwargs):
21962196
raise TypeError(msg.format(op=name))
21972197
return func(**kwargs)
21982198

2199-
def min(self, numeric_only=None, **kwargs):
2199+
@deprecate_kwarg(old_arg_name="numeric_only", new_arg_name="skipna")
2200+
def min(self, skipna=True, **kwargs):
22002201
"""
22012202
The minimum value of the object.
22022203
@@ -2212,17 +2213,18 @@ def min(self, numeric_only=None, **kwargs):
22122213
min : the minimum of this `Categorical`
22132214
"""
22142215
self.check_for_ordered("min")
2215-
if numeric_only:
2216-
good = self._codes != -1
2217-
pointer = self._codes[good].min(**kwargs)
2216+
good = self._codes != -1
2217+
if good.any():
2218+
if skipna:
2219+
pointer = self._codes[good].min(**kwargs)
2220+
else:
2221+
return np.nan
22182222
else:
22192223
pointer = self._codes.min(**kwargs)
2220-
if pointer == -1:
2221-
return np.nan
2222-
else:
2223-
return self.categories[pointer]
2224+
return self.categories[pointer]
22242225

2225-
def max(self, numeric_only=None, **kwargs):
2226+
@deprecate_kwarg(old_arg_name="numeric_only", new_arg_name="skipna")
2227+
def max(self, skipna=True, **kwargs):
22262228
"""
22272229
The maximum value of the object.
22282230
@@ -2238,15 +2240,15 @@ def max(self, numeric_only=None, **kwargs):
22382240
max : the maximum of this `Categorical`
22392241
"""
22402242
self.check_for_ordered("max")
2241-
if numeric_only:
2242-
good = self._codes != -1
2243-
pointer = self._codes[good].max(**kwargs)
2243+
good = self._codes != -1
2244+
if good.any():
2245+
if skipna:
2246+
pointer = self._codes[good].max(**kwargs)
2247+
else:
2248+
return np.nan
22442249
else:
22452250
pointer = self._codes.max(**kwargs)
2246-
if pointer == -1:
2247-
return np.nan
2248-
else:
2249-
return self.categories[pointer]
2251+
return self.categories[pointer]
22502252

22512253
def mode(self, dropna=True):
22522254
"""

pandas/core/series.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3980,9 +3980,7 @@ def _reduce(
39803980
self._get_axis_number(axis)
39813981

39823982
if isinstance(delegate, Categorical):
3983-
# TODO deprecate numeric_only argument for Categorical and use
3984-
# skipna as well, see GH25303
3985-
return delegate._reduce(name, numeric_only=numeric_only, **kwds)
3983+
return delegate._reduce(name, skipna=skipna, **kwds)
39863984
elif isinstance(delegate, ExtensionArray):
39873985
# dispatch to ExtensionArray interface
39883986
return delegate._reduce(name, skipna=skipna, **kwds)

pandas/tests/arrays/categorical/test_analytics.py

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -38,29 +38,38 @@ def test_min_max(self):
3838
cat = Categorical(
3939
[np.nan, "b", "c", np.nan], categories=["d", "c", "b", "a"], ordered=True
4040
)
41-
_min = cat.min()
42-
_max = cat.max()
41+
_min = cat.min(skipna=False)
42+
_max = cat.max(skipna=False)
4343
assert np.isnan(_min)
44-
assert _max == "b"
44+
assert np.isnan(_max)
4545

46-
_min = cat.min(numeric_only=True)
46+
_min = cat.min()
4747
assert _min == "c"
48-
_max = cat.max(numeric_only=True)
48+
_max = cat.max()
4949
assert _max == "b"
5050

5151
cat = Categorical(
5252
[np.nan, 1, 2, np.nan], categories=[5, 4, 3, 2, 1], ordered=True
5353
)
54-
_min = cat.min()
55-
_max = cat.max()
54+
_min = cat.min(skipna=False)
55+
_max = cat.max(skipna=False)
5656
assert np.isnan(_min)
57-
assert _max == 1
57+
assert np.isnan(_max)
5858

59-
_min = cat.min(numeric_only=True)
59+
_min = cat.min()
6060
assert _min == 2
61-
_max = cat.max(numeric_only=True)
61+
_max = cat.max()
6262
assert _max == 1
6363

64+
@pytest.mark.parametrize("method", ["min", "max"])
65+
def test_deprecate_numeric_only_min_max(self, method):
66+
# GH 25303
67+
cat = Categorical(
68+
[np.nan, 1, 2, np.nan], categories=[5, 4, 3, 2, 1], ordered=True
69+
)
70+
with tm.assert_produces_warning(expected_warning=FutureWarning):
71+
getattr(cat, method)(numeric_only=False)
72+
6473
@pytest.mark.parametrize(
6574
"values,categories,exp_mode",
6675
[

pandas/tests/reductions/test_reductions.py

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1028,7 +1028,7 @@ def test_min_max(self):
10281028
)
10291029
_min = cat.min()
10301030
_max = cat.max()
1031-
assert np.isnan(_min)
1031+
assert _min == "c"
10321032
assert _max == "b"
10331033

10341034
cat = Series(
@@ -1038,30 +1038,24 @@ def test_min_max(self):
10381038
)
10391039
_min = cat.min()
10401040
_max = cat.max()
1041-
assert np.isnan(_min)
1041+
assert _min == 2
10421042
assert _max == 1
10431043

1044-
def test_min_max_numeric_only(self):
1045-
# TODO deprecate numeric_only argument for Categorical and use
1046-
# skipna as well, see GH25303
1044+
def test_min_max_skipna(self):
1045+
# GH 25303
10471046
cat = Series(
10481047
Categorical(["a", "b", np.nan, "a"], categories=["b", "a"], ordered=True)
10491048
)
10501049

10511050
_min = cat.min()
10521051
_max = cat.max()
1053-
assert np.isnan(_min)
1054-
assert _max == "a"
1055-
1056-
_min = cat.min(numeric_only=True)
1057-
_max = cat.max(numeric_only=True)
10581052
assert _min == "b"
10591053
assert _max == "a"
10601054

1061-
_min = cat.min(numeric_only=False)
1062-
_max = cat.max(numeric_only=False)
1055+
_min = cat.min(skipna=False)
1056+
_max = cat.max(skipna=False)
10631057
assert np.isnan(_min)
1064-
assert _max == "a"
1058+
assert np.isnan(_max)
10651059

10661060

10671061
class TestSeriesMode:

0 commit comments

Comments
 (0)