diff --git a/doc/source/whatsnew/v1.1.0.rst b/doc/source/whatsnew/v1.1.0.rst index 5fe7d12188860..2f4e961ff433f 100644 --- a/doc/source/whatsnew/v1.1.0.rst +++ b/doc/source/whatsnew/v1.1.0.rst @@ -397,6 +397,7 @@ Categorical - Bug where :class:`Categorical` comparison operator ``__ne__`` would incorrectly evaluate to ``False`` when either element was missing (:issue:`32276`) - :meth:`Categorical.fillna` now accepts :class:`Categorical` ``other`` argument (:issue:`32420`) - Bug where :meth:`Categorical.replace` would replace with ``NaN`` whenever the new value and replacement value were equal (:issue:`33288`) +- Bug where an ordered :class:`Categorical` containing only ``NaN`` values would raise rather than returning ``NaN`` when taking the minimum or maximum (:issue:`33450`) Datetimelike ^^^^^^^^^^^^ diff --git a/pandas/core/arrays/categorical.py b/pandas/core/arrays/categorical.py index c9b8db28e0cf6..b3fb3459891e0 100644 --- a/pandas/core/arrays/categorical.py +++ b/pandas/core/arrays/categorical.py @@ -2143,7 +2143,7 @@ def min(self, skipna=True): good = self._codes != -1 if not good.all(): - if skipna: + if skipna and good.any(): pointer = self._codes[good].min() else: return np.nan @@ -2178,7 +2178,7 @@ def max(self, skipna=True): good = self._codes != -1 if not good.all(): - if skipna: + if skipna and good.any(): pointer = self._codes[good].max() else: return np.nan diff --git a/pandas/tests/arrays/categorical/test_analytics.py b/pandas/tests/arrays/categorical/test_analytics.py index c470f677b5386..67b491165b8cc 100644 --- a/pandas/tests/arrays/categorical/test_analytics.py +++ b/pandas/tests/arrays/categorical/test_analytics.py @@ -88,6 +88,14 @@ def test_min_max_with_nan(self, skipna): assert _min == 2 assert _max == 1 + @pytest.mark.parametrize("function", ["min", "max"]) + @pytest.mark.parametrize("skipna", [True, False]) + def test_min_max_only_nan(self, function, skipna): + # https://github.com/pandas-dev/pandas/issues/33450 + cat = Categorical([np.nan], categories=[1, 2], ordered=True) + result = getattr(cat, function)(skipna=skipna) + assert result is np.nan + @pytest.mark.parametrize("method", ["min", "max"]) def test_deprecate_numeric_only_min_max(self, method): # GH 25303