diff --git a/doc/source/whatsnew/v2.0.0.rst b/doc/source/whatsnew/v2.0.0.rst index 87c19ab164c82..67b7213801ce8 100644 --- a/doc/source/whatsnew/v2.0.0.rst +++ b/doc/source/whatsnew/v2.0.0.rst @@ -190,6 +190,7 @@ Removal of prior version deprecations/changes - Removed argument ``tz`` from :meth:`Period.to_timestamp`, use ``obj.to_timestamp(...).tz_localize(tz)`` instead (:issue:`34522`) - Removed argument ``is_copy`` from :meth:`DataFrame.take` and :meth:`Series.take` (:issue:`30615`) - Removed argument ``kind`` from :meth:`Index.get_slice_bound`, :meth:`Index.slice_indexer` and :meth:`Index.slice_locs` (:issue:`41378`) +- Removed argument ``inplace`` from :meth:`Categorical.remove_unused_categories` (:issue:`37918`) - Disallow passing non-round floats to :class:`Timestamp` with ``unit="M"`` or ``unit="Y"`` (:issue:`47266`) - Remove keywords ``convert_float`` and ``mangle_dupe_cols`` from :func:`read_excel` (:issue:`41176`) - Disallow passing non-keyword arguments to :func:`read_excel` except ``io`` and ``sheet_name`` (:issue:`34418`) diff --git a/pandas/core/arrays/categorical.py b/pandas/core/arrays/categorical.py index 9326b84f8e3be..b3650173e41ef 100644 --- a/pandas/core/arrays/categorical.py +++ b/pandas/core/arrays/categorical.py @@ -1393,35 +1393,14 @@ def remove_categories(self, removals, inplace=no_default): new_categories, ordered=self.ordered, rename=False, inplace=inplace ) - @overload - def remove_unused_categories( - self, *, inplace: Literal[False] | NoDefault = ... - ) -> Categorical: - ... - - @overload - def remove_unused_categories(self, *, inplace: Literal[True]) -> None: - ... - - @deprecate_nonkeyword_arguments(version=None, allowed_args=["self"]) - def remove_unused_categories( - self, inplace: bool | NoDefault = no_default - ) -> Categorical | None: + def remove_unused_categories(self) -> Categorical: """ Remove categories which are not used. - Parameters - ---------- - inplace : bool, default False - Whether or not to drop unused categories inplace or return a copy of - this categorical with unused categories dropped. - - .. deprecated:: 1.2.0 - Returns ------- - cat : Categorical or None - Categorical with unused categories dropped or None if ``inplace=True``. + cat : Categorical + Categorical with unused categories dropped. See Also -------- @@ -1448,33 +1427,20 @@ def remove_unused_categories( ['a', 'c', 'a', 'c', 'c'] Categories (2, object): ['a', 'c'] """ - if inplace is not no_default: - warn( - "The `inplace` parameter in pandas.Categorical." - "remove_unused_categories is deprecated and " - "will be removed in a future version.", - FutureWarning, - stacklevel=find_stack_level(), - ) - else: - inplace = False - - inplace = validate_bool_kwarg(inplace, "inplace") - cat = self if inplace else self.copy() - idx, inv = np.unique(cat._codes, return_inverse=True) + idx, inv = np.unique(self._codes, return_inverse=True) if idx.size != 0 and idx[0] == -1: # na sentinel idx, inv = idx[1:], inv - 1 - new_categories = cat.dtype.categories.take(idx) + new_categories = self.dtype.categories.take(idx) new_dtype = CategoricalDtype._from_fastpath( new_categories, ordered=self.ordered ) new_codes = coerce_indexer_dtype(inv, new_dtype.categories) + + cat = self.copy() NDArrayBacked.__init__(cat, new_codes, new_dtype) - if not inplace: - return cat - return None + return cat # ------------------------------------------------------------------ diff --git a/pandas/tests/arrays/categorical/test_analytics.py b/pandas/tests/arrays/categorical/test_analytics.py index e9f4be11ee4b7..2723b838c41a2 100644 --- a/pandas/tests/arrays/categorical/test_analytics.py +++ b/pandas/tests/arrays/categorical/test_analytics.py @@ -363,11 +363,6 @@ def test_validate_inplace_raises(self, value): # issue #37643 inplace kwarg deprecated cat.remove_categories(removals=["D", "E", "F"], inplace=value) - with pytest.raises(ValueError, match=msg): - with tm.assert_produces_warning(FutureWarning): - # issue #37643 inplace kwarg deprecated - cat.remove_unused_categories(inplace=value) - with pytest.raises(ValueError, match=msg): cat.sort_values(inplace=value) diff --git a/pandas/tests/arrays/categorical/test_api.py b/pandas/tests/arrays/categorical/test_api.py index 03bd1c522838d..2f13d4ee0dd40 100644 --- a/pandas/tests/arrays/categorical/test_api.py +++ b/pandas/tests/arrays/categorical/test_api.py @@ -422,13 +422,6 @@ def test_remove_unused_categories(self): tm.assert_index_equal(res.categories, exp_categories_dropped) tm.assert_index_equal(c.categories, exp_categories_all) - with tm.assert_produces_warning(FutureWarning): - # issue #37643 inplace kwarg deprecated - res = c.remove_unused_categories(inplace=True) - - tm.assert_index_equal(c.categories, exp_categories_dropped) - assert res is None - # with NaN values (GH11599) c = Categorical(["a", "b", "c", np.nan], categories=["a", "b", "c", "d", "e"]) res = c.remove_unused_categories() diff --git a/pandas/tests/series/accessors/test_cat_accessor.py b/pandas/tests/series/accessors/test_cat_accessor.py index 750e84b8cde08..48a01f0018775 100644 --- a/pandas/tests/series/accessors/test_cat_accessor.py +++ b/pandas/tests/series/accessors/test_cat_accessor.py @@ -78,17 +78,6 @@ def test_cat_accessor_no_new_attributes(self): with pytest.raises(AttributeError, match="You cannot add any new attribute"): cat.cat.xlabel = "a" - def test_cat_accessor_updates_on_inplace(self): - ser = Series(list("abc")).astype("category") - return_value = ser.drop(0, inplace=True) - assert return_value is None - - with tm.assert_produces_warning(FutureWarning): - return_value = ser.cat.remove_unused_categories(inplace=True) - - assert return_value is None - assert len(ser.cat.categories) == 2 - def test_categorical_delegations(self): # invalid accessor