Skip to content

Commit 75a79e7

Browse files
authored
API/DEPR: Rename DataFrame.applymap to DataFrame.map (#52364)
1 parent b661313 commit 75a79e7

File tree

19 files changed

+143
-78
lines changed

19 files changed

+143
-78
lines changed

doc/source/development/roadmap.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ Numba-accelerated operations
179179

180180
`Numba <https://numba.pydata.org>`__ is a JIT compiler for Python code. We'd like to provide
181181
ways for users to apply their own Numba-jitted functions where pandas accepts user-defined functions
182-
(for example, :meth:`Series.apply`, :meth:`DataFrame.apply`, :meth:`DataFrame.applymap`,
182+
(for example, :meth:`Series.apply`, :meth:`DataFrame.apply`, :meth:`DataFrame.map`,
183183
and in groupby and window contexts). This will improve the performance of
184184
user-defined-functions in these operations by staying within compiled code.
185185

doc/source/reference/frame.rst

+1
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ Function application, GroupBy & window
116116
:toctree: api/
117117

118118
DataFrame.apply
119+
DataFrame.map
119120
DataFrame.applymap
120121
DataFrame.pipe
121122
DataFrame.agg

doc/source/user_guide/basics.rst

+3-3
Original file line numberDiff line numberDiff line change
@@ -758,7 +758,7 @@ on an entire ``DataFrame`` or ``Series``, row- or column-wise, or elementwise.
758758
1. `Tablewise Function Application`_: :meth:`~DataFrame.pipe`
759759
2. `Row or Column-wise Function Application`_: :meth:`~DataFrame.apply`
760760
3. `Aggregation API`_: :meth:`~DataFrame.agg` and :meth:`~DataFrame.transform`
761-
4. `Applying Elementwise Functions`_: :meth:`~DataFrame.applymap`
761+
4. `Applying Elementwise Functions`_: :meth:`~DataFrame.map`
762762

763763
.. _basics.pipe:
764764

@@ -1170,7 +1170,7 @@ Applying elementwise functions
11701170
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
11711171

11721172
Since not all functions can be vectorized (accept NumPy arrays and return
1173-
another array or value), the methods :meth:`~DataFrame.applymap` on DataFrame
1173+
another array or value), the methods :meth:`~DataFrame.map` on DataFrame
11741174
and analogously :meth:`~Series.map` on Series accept any Python function taking
11751175
a single value and returning a single value. For example:
11761176

@@ -1187,7 +1187,7 @@ a single value and returning a single value. For example:
11871187
return len(str(x))
11881188
11891189
df4["one"].map(f)
1190-
df4.applymap(f)
1190+
df4.map(f)
11911191
11921192
:meth:`Series.map` has an additional feature; it can be used to easily
11931193
"link" or "map" values defined by a secondary series. This is closely related

doc/source/user_guide/cookbook.rst

+2-2
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,7 @@ Ambiguity arises when an index consists of integers with a non-zero start or non
242242
New columns
243243
***********
244244

245-
`Efficiently and dynamically creating new columns using applymap
245+
`Efficiently and dynamically creating new columns using DataFrame.map (previously named applymap)
246246
<https://stackoverflow.com/questions/16575868/efficiently-creating-additional-columns-in-a-pandas-dataframe-using-map>`__
247247

248248
.. ipython:: python
@@ -254,7 +254,7 @@ New columns
254254
new_cols = [str(x) + "_cat" for x in source_cols]
255255
categories = {1: "Alpha", 2: "Beta", 3: "Charlie"}
256256
257-
df[new_cols] = df[source_cols].applymap(categories.get)
257+
df[new_cols] = df[source_cols].map(categories.get)
258258
df
259259
260260
`Keep other columns when using min() with groupby

doc/source/user_guide/style.ipynb

+2-2
Original file line numberDiff line numberDiff line change
@@ -352,7 +352,7 @@
352352
"\n",
353353
"- Using [.set_table_styles()][table] to control broader areas of the table with specified internal CSS. Although table styles allow the flexibility to add CSS selectors and properties controlling all individual parts of the table, they are unwieldy for individual cell specifications. Also, note that table styles cannot be exported to Excel. \n",
354354
"- Using [.set_td_classes()][td_class] to directly link either external CSS classes to your data cells or link the internal CSS classes created by [.set_table_styles()][table]. See [here](#Setting-Classes-and-Linking-to-External-CSS). These cannot be used on column header rows or indexes, and also won't export to Excel. \n",
355-
"- Using the [.apply()][apply] and [.applymap()][applymap] functions to add direct internal CSS to specific data cells. See [here](#Styler-Functions). As of v1.4.0 there are also methods that work directly on column header rows or indexes; [.apply_index()][applyindex] and [.applymap_index()][applymapindex]. Note that only these methods add styles that will export to Excel. These methods work in a similar way to [DataFrame.apply()][dfapply] and [DataFrame.applymap()][dfapplymap].\n",
355+
"- Using the [.apply()][apply] and [.applymap()][applymap] functions to add direct internal CSS to specific data cells. See [here](#Styler-Functions). As of v1.4.0 there are also methods that work directly on column header rows or indexes; [.apply_index()][applyindex] and [.applymap_index()][applymapindex]. Note that only these methods add styles that will export to Excel. These methods work in a similar way to [DataFrame.apply()][dfapply] and [DataFrame.map()][dfmap].\n",
356356
"\n",
357357
"[table]: ../reference/api/pandas.io.formats.style.Styler.set_table_styles.rst\n",
358358
"[styler]: ../reference/api/pandas.io.formats.style.Styler.rst\n",
@@ -362,7 +362,7 @@
362362
"[applyindex]: ../reference/api/pandas.io.formats.style.Styler.apply_index.rst\n",
363363
"[applymapindex]: ../reference/api/pandas.io.formats.style.Styler.applymap_index.rst\n",
364364
"[dfapply]: ../reference/api/pandas.DataFrame.apply.rst\n",
365-
"[dfapplymap]: ../reference/api/pandas.DataFrame.applymap.rst"
365+
"[dfmap]: ../reference/api/pandas.DataFrame.map.rst"
366366
]
367367
},
368368
{

doc/source/user_guide/visualization.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -1709,7 +1709,7 @@ Colormaps can also be used other plot types, like bar charts:
17091709
17101710
.. ipython:: python
17111711
1712-
dd = pd.DataFrame(np.random.randn(10, 10)).applymap(abs)
1712+
dd = pd.DataFrame(np.random.randn(10, 10)).map(abs)
17131713
dd = dd.cumsum()
17141714
17151715
plt.figure();

doc/source/whatsnew/v2.1.0.rst

+5-2
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ enhancement1
2525
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2626

2727
When given a callable, :meth:`Series.map` applies the callable to all elements of the :class:`Series`.
28-
Similarly, :meth:`DataFrame.applymap` applies the callable to all elements of the :class:`DataFrame`,
28+
Similarly, :meth:`DataFrame.map` applies the callable to all elements of the :class:`DataFrame`,
2929
while :meth:`Index.map` applies the callable to all elements of the :class:`Index`.
3030

3131
Frequently, it is not desirable to apply the callable to nan-like values of the array and to avoid doing
@@ -59,10 +59,12 @@ and ``na_action="ignore"`` did not work correctly for any ``ExtensionArray`` sub
5959
ser = pd.Series(["a", "b", np.nan], dtype="category")
6060
ser.map(str.upper, na_action="ignore")
6161
df = pd.DataFrame(ser)
62-
df.applymap(str.upper, na_action="ignore")
62+
df.map(str.upper, na_action="ignore")
6363
idx = pd.Index(ser)
6464
idx.map(str.upper, na_action="ignore")
6565
66+
Notice also that in this version, :meth:`DataFrame.map` been added and :meth:`DataFrame.applymap` has been deprecated. :meth:`DataFrame.map` has the same functionality as :meth:`DataFrame.applymap`, but the new name better communicate that this is the :class:`DataFrame` version of :meth:`Series.map` (:issue:`52353`).
67+
6668
Also, note that :meth:`Categorical.map` implicitly has had its ``na_action`` set to ``"ignore"`` by default.
6769
This has been deprecated and will :meth:`Categorical.map` in the future change the default
6870
to ``na_action=None``, like for all the other array types.
@@ -224,6 +226,7 @@ Deprecations
224226
- Deprecated :func:`is_datetime64tz_dtype`, check ``isinstance(dtype, pd.DatetimeTZDtype)`` instead (:issue:`52607`)
225227
- Deprecated :func:`is_int64_dtype`, check ``dtype == np.dtype(np.int64)`` instead (:issue:`52564`)
226228
- Deprecated :func:`is_interval_dtype`, check ``isinstance(dtype, pd.IntervalDtype)`` instead (:issue:`52607`)
229+
- Deprecated :meth:`DataFrame.applymap`. Use the new :meth:`DataFrame.map` method instead (:issue:`52353`)
227230
- Deprecated :meth:`DataFrame.swapaxes` and :meth:`Series.swapaxes`, use :meth:`DataFrame.transpose` or :meth:`Series.transpose` instead (:issue:`51946`)
228231
- Deprecated ``freq`` parameter in :class:`PeriodArray` constructor, pass ``dtype`` instead (:issue:`52462`)
229232
- Deprecated behavior of :meth:`Series.dt.to_pydatetime`, in a future version this will return a :class:`Series` containing python ``datetime`` objects instead of an ``ndarray`` of datetimes; this matches the behavior of other :meth:`Series.dt` properties (:issue:`20306`)

pandas/core/frame.py

+66-7
Original file line numberDiff line numberDiff line change
@@ -9673,7 +9673,7 @@ def apply(
96739673
96749674
See Also
96759675
--------
9676-
DataFrame.applymap: For elementwise operations.
9676+
DataFrame.map: For elementwise operations.
96779677
DataFrame.aggregate: Only perform aggregating type operations.
96789678
DataFrame.transform: Only perform transforming type operations.
96799679
@@ -9765,12 +9765,16 @@ def apply(
97659765
)
97669766
return op.apply().__finalize__(self, method="apply")
97679767

9768-
def applymap(
9768+
def map(
97699769
self, func: PythonFuncType, na_action: str | None = None, **kwargs
97709770
) -> DataFrame:
97719771
"""
97729772
Apply a function to a Dataframe elementwise.
97739773
9774+
.. versionadded:: 2.1.0
9775+
9776+
DataFrame.applymap was deprecated and renamed to DataFrame.map.
9777+
97749778
This method applies a function that accepts and returns a scalar
97759779
to every element of a DataFrame.
97769780
@@ -9798,6 +9802,7 @@ def applymap(
97989802
--------
97999803
DataFrame.apply : Apply a function along input axis of DataFrame.
98009804
DataFrame.replace: Replace values given in `to_replace` with `value`.
9805+
Series.map : Apply a function elementwise on a Series.
98019806
98029807
Examples
98039808
--------
@@ -9807,7 +9812,7 @@ def applymap(
98079812
0 1.000 2.120
98089813
1 3.356 4.567
98099814
9810-
>>> df.applymap(lambda x: len(str(x)))
9815+
>>> df.map(lambda x: len(str(x)))
98119816
0 1
98129817
0 3 4
98139818
1 5 5
@@ -9816,20 +9821,20 @@ def applymap(
98169821
98179822
>>> df_copy = df.copy()
98189823
>>> df_copy.iloc[0, 0] = pd.NA
9819-
>>> df_copy.applymap(lambda x: len(str(x)), na_action='ignore')
9824+
>>> df_copy.map(lambda x: len(str(x)), na_action='ignore')
98209825
0 1
98219826
0 NaN 4
98229827
1 5.0 5
98239828
98249829
Note that a vectorized version of `func` often exists, which will
98259830
be much faster. You could square each number elementwise.
98269831
9827-
>>> df.applymap(lambda x: x**2)
9832+
>>> df.map(lambda x: x**2)
98289833
0 1
98299834
0 1.000000 4.494400
98309835
1 11.262736 20.857489
98319836
9832-
But it's better to avoid applymap in that case.
9837+
But it's better to avoid map in that case.
98339838
98349839
>>> df ** 2
98359840
0 1
@@ -9849,7 +9854,61 @@ def applymap(
98499854
def infer(x):
98509855
return x._map_values(func, na_action=na_action)
98519856

9852-
return self.apply(infer).__finalize__(self, "applymap")
9857+
return self.apply(infer).__finalize__(self, "map")
9858+
9859+
def applymap(
9860+
self, func: PythonFuncType, na_action: str | None = None, **kwargs
9861+
) -> DataFrame:
9862+
"""
9863+
Apply a function to a Dataframe elementwise.
9864+
9865+
.. deprecated:: 2.1.0
9866+
9867+
DataFrame.applymap has been deprecated. Use DataFrame.map instead.
9868+
9869+
This method applies a function that accepts and returns a scalar
9870+
to every element of a DataFrame.
9871+
9872+
Parameters
9873+
----------
9874+
func : callable
9875+
Python function, returns a single value from a single value.
9876+
na_action : {None, 'ignore'}, default None
9877+
If ‘ignore’, propagate NaN values, without passing them to func.
9878+
**kwargs
9879+
Additional keyword arguments to pass as keywords arguments to
9880+
`func`.
9881+
9882+
Returns
9883+
-------
9884+
DataFrame
9885+
Transformed DataFrame.
9886+
9887+
See Also
9888+
--------
9889+
DataFrame.apply : Apply a function along input axis of DataFrame.
9890+
DataFrame.map : Apply a function along input axis of DataFrame.
9891+
DataFrame.replace: Replace values given in `to_replace` with `value`.
9892+
9893+
Examples
9894+
--------
9895+
>>> df = pd.DataFrame([[1, 2.12], [3.356, 4.567]])
9896+
>>> df
9897+
0 1
9898+
0 1.000 2.120
9899+
1 3.356 4.567
9900+
9901+
>>> df.map(lambda x: len(str(x)))
9902+
0 1
9903+
0 3 4
9904+
1 5 5
9905+
"""
9906+
warnings.warn(
9907+
"DataFrame.applymap has been deprecated. Use DataFrame.map instead.",
9908+
FutureWarning,
9909+
stacklevel=find_stack_level(),
9910+
)
9911+
return self.map(func, na_action=na_action, **kwargs)
98539912

98549913
# ----------------------------------------------------------------------
98559914
# Merging / joining methods

pandas/core/generic.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -5942,7 +5942,7 @@ def pipe(
59425942
See Also
59435943
--------
59445944
DataFrame.apply : Apply a function along input axis of DataFrame.
5945-
DataFrame.applymap : Apply a function elementwise on a whole DataFrame.
5945+
DataFrame.map : Apply a function elementwise on a whole DataFrame.
59465946
Series.map : Apply a mapping correspondence on a
59475947
:class:`~pandas.Series`.
59485948

pandas/core/series.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -4250,7 +4250,7 @@ def map(
42504250
Series.apply : For applying more complex functions on a Series.
42514251
Series.replace: Replace values given in `to_replace` with `value`.
42524252
DataFrame.apply : Apply a function row-/column-wise.
4253-
DataFrame.applymap : Apply a function elementwise on a whole DataFrame.
4253+
DataFrame.map : Apply a function elementwise on a whole DataFrame.
42544254
42554255
Notes
42564256
-----

pandas/core/shared_docs.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -609,7 +609,7 @@
609609
DataFrame.fillna : Fill NA values.
610610
Series.where : Replace values based on boolean condition.
611611
DataFrame.where : Replace values based on boolean condition.
612-
DataFrame.applymap: Apply a function to a Dataframe elementwise.
612+
DataFrame.map: Apply a function to a Dataframe elementwise.
613613
Series.map: Map values of Series according to an input mapping or function.
614614
Series.str.replace : Simple string replacement.
615615

pandas/io/formats/style.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -1813,7 +1813,7 @@ def _apply_index(
18131813
if method == "apply":
18141814
result = data.apply(func, axis=0, **kwargs)
18151815
elif method == "applymap":
1816-
result = data.applymap(func, **kwargs)
1816+
result = data.map(func, **kwargs)
18171817

18181818
self._update_ctx_header(result, axis)
18191819
return self
@@ -1938,7 +1938,7 @@ def _applymap(
19381938
if subset is None:
19391939
subset = IndexSlice[:]
19401940
subset = non_reducing_slice(subset)
1941-
result = self.data.loc[subset].applymap(func)
1941+
result = self.data.loc[subset].map(func)
19421942
self._update_ctx(result)
19431943
return self
19441944

pandas/io/json/_json.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -365,7 +365,7 @@ def __init__(
365365
obj = obj.copy()
366366
timedeltas = obj.select_dtypes(include=["timedelta"]).columns
367367
if len(timedeltas):
368-
obj[timedeltas] = obj[timedeltas].applymap(lambda x: x.isoformat())
368+
obj[timedeltas] = obj[timedeltas].map(lambda x: x.isoformat())
369369
# Convert PeriodIndex to datetimes before serializing
370370
if isinstance(obj.index.dtype, PeriodDtype):
371371
obj.index = obj.index.to_timestamp()

0 commit comments

Comments
 (0)