diff --git a/doc/source/whatsnew/v3.0.0.rst b/doc/source/whatsnew/v3.0.0.rst index c932d793038c2..143bf48f189e9 100644 --- a/doc/source/whatsnew/v3.0.0.rst +++ b/doc/source/whatsnew/v3.0.0.rst @@ -243,6 +243,7 @@ Removal of prior version deprecations/changes - Removed the "closed" and "unit" keywords in :meth:`TimedeltaIndex.__new__` (:issue:`52628`, :issue:`55499`) - All arguments in :meth:`Index.sort_values` are now keyword only (:issue:`56493`) - All arguments in :meth:`Series.to_dict` are now keyword only (:issue:`56493`) +- Changed the default value of ``na_action`` in :meth:`Categorical.map` to ``None`` (:issue:`51645`) - Changed the default value of ``observed`` in :meth:`DataFrame.groupby` and :meth:`Series.groupby` to ``True`` (:issue:`51811`) - Enforce deprecation in :func:`testing.assert_series_equal` and :func:`testing.assert_frame_equal` with object dtype and mismatched null-like values, which are now considered not-equal (:issue:`18463`) - Enforced deprecation ``all`` and ``any`` reductions with ``datetime64``, :class:`DatetimeTZDtype`, and :class:`PeriodDtype` dtypes (:issue:`58029`) diff --git a/pandas/core/arrays/arrow/array.py b/pandas/core/arrays/arrow/array.py index 96e77e4b920d6..e403ecfdef4bc 100644 --- a/pandas/core/arrays/arrow/array.py +++ b/pandas/core/arrays/arrow/array.py @@ -1425,7 +1425,7 @@ def to_numpy( result[~mask] = data[~mask]._pa_array.to_numpy() return result - def map(self, mapper, na_action=None): + def map(self, mapper, na_action: Literal["ignore"] | None = None): if is_numeric_dtype(self.dtype): return map_array(self.to_numpy(), mapper, na_action=na_action) else: diff --git a/pandas/core/arrays/base.py b/pandas/core/arrays/base.py index ae22f1344e3cf..380d2516a44ed 100644 --- a/pandas/core/arrays/base.py +++ b/pandas/core/arrays/base.py @@ -2270,7 +2270,7 @@ def __array_ufunc__(self, ufunc: np.ufunc, method: str, *inputs, **kwargs): return arraylike.default_array_ufunc(self, ufunc, method, *inputs, **kwargs) - def map(self, mapper, na_action=None): + def map(self, mapper, na_action: Literal["ignore"] | None = None): """ Map values using an input mapping or function. diff --git a/pandas/core/arrays/categorical.py b/pandas/core/arrays/categorical.py index 381eaaa167d42..8fd3c198b7adb 100644 --- a/pandas/core/arrays/categorical.py +++ b/pandas/core/arrays/categorical.py @@ -1483,7 +1483,7 @@ def remove_unused_categories(self) -> Self: def map( self, mapper, - na_action: Literal["ignore"] | None | lib.NoDefault = lib.no_default, + na_action: Literal["ignore"] | None = None, ): """ Map categories using an input mapping or function. @@ -1501,15 +1501,10 @@ def map( ---------- mapper : function, dict, or Series Mapping correspondence. - na_action : {None, 'ignore'}, default 'ignore' + na_action : {None, 'ignore'}, default None If 'ignore', propagate NaN values, without passing them to the mapping correspondence. - .. deprecated:: 2.1.0 - - The default value of 'ignore' has been deprecated and will be changed to - None in the future. - Returns ------- pandas.Categorical or pandas.Index @@ -1561,17 +1556,6 @@ def map( >>> cat.map({"a": "first", "b": "second"}, na_action=None) Index(['first', 'second', nan], dtype='object') """ - if na_action is lib.no_default: - warnings.warn( - "The default value of 'ignore' for the `na_action` parameter in " - "pandas.Categorical.map is deprecated and will be " - "changed to 'None' in a future version. Please set na_action to the " - "desired value to avoid seeing this warning", - FutureWarning, - stacklevel=find_stack_level(), - ) - na_action = "ignore" - assert callable(mapper) or is_dict_like(mapper) new_categories = self.categories.map(mapper) diff --git a/pandas/core/arrays/datetimelike.py b/pandas/core/arrays/datetimelike.py index ab17ae43215d2..26095e0af7878 100644 --- a/pandas/core/arrays/datetimelike.py +++ b/pandas/core/arrays/datetimelike.py @@ -728,7 +728,7 @@ def _unbox(self, other) -> np.int64 | np.datetime64 | np.timedelta64 | np.ndarra # pandas assumes they're there. @ravel_compat - def map(self, mapper, na_action=None): + def map(self, mapper, na_action: Literal["ignore"] | None = None): from pandas import Index result = map_array(self, mapper, na_action=na_action) diff --git a/pandas/core/arrays/masked.py b/pandas/core/arrays/masked.py index e77c998e796a9..04cffcaaa5f04 100644 --- a/pandas/core/arrays/masked.py +++ b/pandas/core/arrays/masked.py @@ -1318,7 +1318,7 @@ def max(self, *, skipna: bool = True, axis: AxisInt | None = 0, **kwargs): ) return self._wrap_reduction_result("max", result, skipna=skipna, axis=axis) - def map(self, mapper, na_action=None): + def map(self, mapper, na_action: Literal["ignore"] | None = None): return map_array(self.to_numpy(), mapper, na_action=na_action) @overload diff --git a/pandas/core/arrays/sparse/array.py b/pandas/core/arrays/sparse/array.py index 42e1cdd337e62..adf8f44377e62 100644 --- a/pandas/core/arrays/sparse/array.py +++ b/pandas/core/arrays/sparse/array.py @@ -1253,7 +1253,7 @@ def astype(self, dtype: AstypeArg | None = None, copy: bool = True): return self._simple_new(sp_values, self.sp_index, dtype) - def map(self, mapper, na_action=None) -> Self: + def map(self, mapper, na_action: Literal["ignore"] | None = None) -> Self: """ Map categories using an input mapping or function. diff --git a/pandas/core/frame.py b/pandas/core/frame.py index 39113cda8b232..a4decab6e8a2b 100644 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -10369,7 +10369,7 @@ def apply( return op.apply().__finalize__(self, method="apply") def map( - self, func: PythonFuncType, na_action: str | None = None, **kwargs + self, func: PythonFuncType, na_action: Literal["ignore"] | None = None, **kwargs ) -> DataFrame: """ Apply a function to a Dataframe elementwise. diff --git a/pandas/tests/arrays/categorical/test_map.py b/pandas/tests/arrays/categorical/test_map.py index 763ca9180e53a..585b207c9b241 100644 --- a/pandas/tests/arrays/categorical/test_map.py +++ b/pandas/tests/arrays/categorical/test_map.py @@ -134,16 +134,3 @@ def test_map_with_dict_or_series(na_action): result = cat.map(mapper, na_action=na_action) # Order of categories in result can be different tm.assert_categorical_equal(result, expected) - - -def test_map_na_action_no_default_deprecated(): - # GH51645 - cat = Categorical(["a", "b", "c"]) - msg = ( - "The default value of 'ignore' for the `na_action` parameter in " - "pandas.Categorical.map is deprecated and will be " - "changed to 'None' in a future version. Please set na_action to the " - "desired value to avoid seeing this warning" - ) - with tm.assert_produces_warning(FutureWarning, match=msg): - cat.map(lambda x: x)