Skip to content

API: Rename arg to func in Series.map #61264

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 11 commits into from
Apr 14, 2025
1 change: 1 addition & 0 deletions doc/source/whatsnew/v3.0.0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -422,6 +422,7 @@ Other Deprecations
- Deprecated parameter ``method`` in :meth:`DataFrame.reindex_like` / :meth:`Series.reindex_like` (:issue:`58667`)
- Deprecated strings ``w``, ``d``, ``MIN``, ``MS``, ``US`` and ``NS`` denoting units in :class:`Timedelta` in favour of ``W``, ``D``, ``min``, ``ms``, ``us`` and ``ns`` (:issue:`59051`)
- Deprecated using ``epoch`` date format in :meth:`DataFrame.to_json` and :meth:`Series.to_json`, use ``iso`` instead. (:issue:`57063`)
- Deprecated the ``arg`` parameter of ``Series.map``; pass the added ``func`` argument instead. (:issue:`61260`)

.. ---------------------------------------------------------------------------
.. _whatsnew_300.prior_deprecations:
Expand Down
28 changes: 22 additions & 6 deletions pandas/core/series.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@
doc,
set_module,
)
from pandas.util._exceptions import (
find_stack_level,
)
from pandas.util._validators import (
validate_ascending,
validate_bool_kwarg,
Expand Down Expand Up @@ -4320,7 +4323,7 @@ def unstack(

def map(
self,
arg: Callable | Mapping | Series,
func: Callable | Mapping | Series | None = None,
na_action: Literal["ignore"] | None = None,
**kwargs,
) -> Series:
Expand All @@ -4333,8 +4336,8 @@ def map(

Parameters
----------
arg : function, collections.abc.Mapping subclass or Series
Mapping correspondence.
func : function, collections.abc.Mapping subclass or Series
Function or mapping correspondence.
na_action : {None, 'ignore'}, default None
If 'ignore', propagate NaN values, without passing them to the
mapping correspondence.
Expand Down Expand Up @@ -4404,9 +4407,22 @@ def map(
3 I am a rabbit
dtype: object
"""
if callable(arg):
arg = functools.partial(arg, **kwargs)
new_values = self._map_values(arg, na_action=na_action)
if func is None:
if "arg" in kwargs:
Comment on lines +4410 to +4411
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Noting this won't be backwards compatible with the use Series.map(arg=foo, func=myfunc) where myfunc is an argument of foo. This seems unlikely enough that I am okay here.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are totally right. In my first implementation I was raising an exception, and then thought it would be better to allow using arg as an argument name of the udf. If we want to be very conservative we could raise now, and stop raising when we remove the deprecation and arg is no longer accepted as the argument name of the function.

But as you, I think is better to just let that unlikely case break compatibility.

# `.map(arg=my_func)`
func = kwargs.pop("arg")
warnings.warn(
"The parameter `arg` has been renamed to `func`, and it "
"will stop being supported in a future version of pandas.",
FutureWarning,
stacklevel=find_stack_level(),
)
else:
raise ValueError("The `func` parameter is required")

if callable(func):
func = functools.partial(func, **kwargs)
new_values = self._map_values(func, na_action=na_action)
return self._constructor(new_values, index=self.index, copy=False).__finalize__(
self, method="map"
)
Expand Down
24 changes: 24 additions & 0 deletions pandas/tests/series/methods/test_map.py
Original file line number Diff line number Diff line change
Expand Up @@ -604,3 +604,27 @@ def test_map_kwargs():
result = Series([2, 4, 5]).map(lambda x, y: x + y, y=2)
expected = Series([4, 6, 7])
tm.assert_series_equal(result, expected)


def test_map_arg_as_kwarg():
with tm.assert_produces_warning(
FutureWarning, match="`arg` has been renamed to `func`"
):
Series([1, 2]).map(arg={})


def test_map_func_and_arg():
# `arg`is considered a normal kwarg that should be passed to the function
result = Series([1, 2]).map(lambda _, arg: arg, arg=3)
expected = Series([3, 3])
tm.assert_series_equal(result, expected)


def test_map_no_func_or_arg():
with pytest.raises(ValueError, match="The `func` parameter is required"):
Series([1, 2]).map()


def test_map_func_is_none():
with pytest.raises(ValueError, match="The `func` parameter is required"):
Series([1, 2]).map(func=None)
Loading