Skip to content

API: Replace na_action parameter in Series/DataFrame/Index.map by the standard skipna #61530

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

Open
wants to merge 9 commits into
base: main
Choose a base branch
from

Conversation

datapythonista
Copy link
Member

We've been consistently using a boolean skipna parameter to let users decide whether missing values should be ignored or not in different methods. The .map method has an awkward na_action=None | "igonre" for the same purpose. I add the standard skipna parameter to the methods, and start the deprecation of the na_action one.

@datapythonista datapythonista added API Design Apply Apply, Aggregate, Transform, Map labels Jun 1, 2025
s = Series([1, 2, 3])
msg = f"na_action must either be 'ignore' or None, {input_na_action} was passed"
with pytest.raises(ValueError, match=msg):
s.map({1: 2}, na_action=input_na_action)
Copy link
Member Author

Choose a reason for hiding this comment

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

These are already tested for DataFrame.map, Series.map and Index.map, together with the warning now. I didn't think it was worth testing the same here again only for Series.

@@ -10719,16 +10725,28 @@ def map(
0 1.000000 4.494400
1 11.262736 20.857489
"""
if na_action not in {"ignore", None}:
raise ValueError(f"na_action must be 'ignore' or None. Got {na_action!r}")
if na_action != lib.no_default:
Copy link
Member Author

Choose a reason for hiding this comment

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

In case it's not obvious, I'm using lib.no_default as a sentinel to know if na_action was set by the user, so we can show them a warning. If I leave the default to None I can't tell if the user call was .map(func) (no warning needed) or .map(func, na_action=None) (warning needed)

"""
return request.param


Copy link
Member Author

Choose a reason for hiding this comment

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

The skipna fixture already exists.

@@ -2541,17 +2541,17 @@ 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: Literal["ignore"] | None = None):
def map(self, mapper, skipna: bool = False):
Copy link
Member

Choose a reason for hiding this comment

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

This is technically a public API since EA authors might have implemented map on their arrays

Copy link
Member Author

Choose a reason for hiding this comment

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

True, I thought about it, but I couldn't find any extension array that implements map, at least in the ones in our ecosystem. And if there is one I'm not aware of, it should call super in order for this to affect them.

I'm ok to add a DeprecationWarning if you think it's better. I thought that in the unlikely case this breaks any code, we may get a report before the release, and see with a specific case what makes more sense here.

I addressed the other comments, thanks for the feedback.

Copy link
Member

Choose a reason for hiding this comment

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

OK if you surveyed other EAs in the ecosystem, I feel more comfortable making this a breaking change. Could you note it in the breaking changes section at least in the v3.0.0.rst whatsnew?

Copy link
Member Author

Choose a reason for hiding this comment

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

I was double checking. pandas-pint does implement map, but it doesn't call super, so this is not used. What I didn't see before is that it does call map_array, which is also having this change.

I'm still not sure if the warning is the best strategy, maybe I'm just overthinking.

@MichaelTiemannOSC, it would be good to have your feedback about this.

Comment on lines 10646 to 10647
skipna: bool = False,
na_action: Literal["ignore"] | None | lib.NoDefault = lib.no_default,
Copy link
Member

Choose a reason for hiding this comment

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

I think these should be switched to not break users passing arguments by position

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
API Design Apply Apply, Aggregate, Transform, Map
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants