From cb0702d8a6c096397d1eae409cb0e1fb2abfd966 Mon Sep 17 00:00:00 2001 From: "alexprincel@gmail.com" Date: Sun, 21 Mar 2021 22:35:34 -0400 Subject: [PATCH 1/2] ENH: applymap get kwargs #39987 --- doc/source/whatsnew/v1.3.0.rst | 1 + pandas/core/frame.py | 8 ++++++-- pandas/tests/apply/test_frame_apply.py | 6 ++++++ 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/doc/source/whatsnew/v1.3.0.rst b/doc/source/whatsnew/v1.3.0.rst index 8deeb3cfae1d3..4055867e09521 100644 --- a/doc/source/whatsnew/v1.3.0.rst +++ b/doc/source/whatsnew/v1.3.0.rst @@ -61,6 +61,7 @@ Other enhancements - :meth:`.Rolling.sum`, :meth:`.Expanding.sum`, :meth:`.Rolling.mean`, :meth:`.Expanding.mean`, :meth:`.Rolling.median`, :meth:`.Expanding.median`, :meth:`.Rolling.max`, :meth:`.Expanding.max`, :meth:`.Rolling.min`, and :meth:`.Expanding.min` now support ``Numba`` execution with the ``engine`` keyword (:issue:`38895`) - :meth:`DataFrame.apply` can now accept NumPy unary operators as strings, e.g. ``df.apply("sqrt")``, which was already the case for :meth:`Series.apply` (:issue:`39116`) - :meth:`DataFrame.apply` can now accept non-callable DataFrame properties as strings, e.g. ``df.apply("size")``, which was already the case for :meth:`Series.apply` (:issue:`39116`) +- :meth:`DataFrame.applymap` can now accept kwargs to pass on to func (:issue:`39987`) - :meth:`Series.apply` can now accept list-like or dictionary-like arguments that aren't lists or dictionaries, e.g. ``ser.apply(np.array(["sum", "mean"]))``, which was already the case for :meth:`DataFrame.apply` (:issue:`39140`) - :meth:`DataFrame.plot.scatter` can now accept a categorical column as the argument to ``c`` (:issue:`12380`, :issue:`31357`) - :meth:`.Styler.set_tooltips` allows on hover tooltips to be added to styled HTML dataframes (:issue:`35643`, :issue:`21266`, :issue:`39317`) diff --git a/pandas/core/frame.py b/pandas/core/frame.py index 2c95e65c70899..3e1b786958f89 100644 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -13,6 +13,7 @@ import collections from collections import abc import datetime +import functools from io import StringIO import itertools import mmap @@ -3045,7 +3046,6 @@ def _ixs(self, i: int, axis: int = 0): # this is a cached value, mark it so result._set_as_cached(label, self) - return result def _get_column_array(self, i: int) -> ArrayLike: @@ -7934,7 +7934,7 @@ def apply( return op.apply() def applymap( - self, func: PythonFuncType, na_action: Optional[str] = None + self, func: PythonFuncType, na_action: Optional[str] = None, **kwargs ) -> DataFrame: """ Apply a function to a Dataframe elementwise. @@ -7948,6 +7948,9 @@ def applymap( Python function, returns a single value from a single value. na_action : {None, 'ignore'}, default None If ‘ignore’, propagate NaN values, without passing them to func. + **kwargs + Additional keyword arguments to pass as keywords arguments to + `func`. .. versionadded:: 1.2 @@ -8002,6 +8005,7 @@ def applymap( f"na_action must be 'ignore' or None. Got {repr(na_action)}" ) ignore_na = na_action == "ignore" + func = functools.partial(func, **kwargs) # if we have a dtype == 'M8[ns]', provide boxed values def infer(x): diff --git a/pandas/tests/apply/test_frame_apply.py b/pandas/tests/apply/test_frame_apply.py index 3532040a2fd7b..eb888fd474dfd 100644 --- a/pandas/tests/apply/test_frame_apply.py +++ b/pandas/tests/apply/test_frame_apply.py @@ -678,6 +678,12 @@ def test_applymap(float_frame): tm.assert_frame_equal(result, frame) +def test_applymap_kwargs(): + result = pd.DataFrame([[1, 2], [3, 4]]).applymap(lambda x, y: x + y, y=2) + expected = pd.DataFrame([[3, 4], [5, 6]]) + tm.assert_frame_equal(result, expected) + + def test_applymap_na_ignore(float_frame): # GH 23803 strlen_frame = float_frame.applymap(lambda x: len(str(x))) From 0dd0bb116a46da8db8b5adae3c3679a64f94bfe0 Mon Sep 17 00:00:00 2001 From: "alexprincel@gmail.com" Date: Mon, 22 Mar 2021 11:26:46 -0400 Subject: [PATCH 2/2] ENH: Add GH and version refs (#40562) --- pandas/core/frame.py | 5 ++++- pandas/tests/apply/test_frame_apply.py | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/pandas/core/frame.py b/pandas/core/frame.py index ca8e935105947..1b07a5b97806e 100644 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -8454,11 +8454,14 @@ def applymap( Python function, returns a single value from a single value. na_action : {None, 'ignore'}, default None If ‘ignore’, propagate NaN values, without passing them to func. + + .. versionadded:: 1.2 + **kwargs Additional keyword arguments to pass as keywords arguments to `func`. - .. versionadded:: 1.2 + .. versionadded:: 1.3 Returns ------- diff --git a/pandas/tests/apply/test_frame_apply.py b/pandas/tests/apply/test_frame_apply.py index 7c5bb93795740..cee8a0218e9e8 100644 --- a/pandas/tests/apply/test_frame_apply.py +++ b/pandas/tests/apply/test_frame_apply.py @@ -561,6 +561,7 @@ def test_applymap(float_frame): def test_applymap_kwargs(): + # GH 40652 result = DataFrame([[1, 2], [3, 4]]).applymap(lambda x, y: x + y, y=2) expected = DataFrame([[3, 4], [5, 6]]) tm.assert_frame_equal(result, expected)