diff --git a/doc/source/development/roadmap.rst b/doc/source/development/roadmap.rst index f2198d1ce521d..2d142453fb735 100644 --- a/doc/source/development/roadmap.rst +++ b/doc/source/development/roadmap.rst @@ -179,7 +179,7 @@ Numba-accelerated operations `Numba `__ is a JIT compiler for Python code. We'd like to provide ways for users to apply their own Numba-jitted functions where pandas accepts user-defined functions -(for example, :meth:`Series.apply`, :meth:`DataFrame.apply`, :meth:`DataFrame.applymap`, +(for example, :meth:`Series.apply`, :meth:`DataFrame.apply`, :meth:`DataFrame.map`, and in groupby and window contexts). This will improve the performance of user-defined-functions in these operations by staying within compiled code. diff --git a/doc/source/reference/frame.rst b/doc/source/reference/frame.rst index ec29f1dc0d67d..fefb02dd916cd 100644 --- a/doc/source/reference/frame.rst +++ b/doc/source/reference/frame.rst @@ -116,6 +116,7 @@ Function application, GroupBy & window :toctree: api/ DataFrame.apply + DataFrame.map DataFrame.applymap DataFrame.pipe DataFrame.agg diff --git a/doc/source/user_guide/basics.rst b/doc/source/user_guide/basics.rst index 16a85ccc74b43..48fcaf85f0f59 100644 --- a/doc/source/user_guide/basics.rst +++ b/doc/source/user_guide/basics.rst @@ -758,7 +758,7 @@ on an entire ``DataFrame`` or ``Series``, row- or column-wise, or elementwise. 1. `Tablewise Function Application`_: :meth:`~DataFrame.pipe` 2. `Row or Column-wise Function Application`_: :meth:`~DataFrame.apply` 3. `Aggregation API`_: :meth:`~DataFrame.agg` and :meth:`~DataFrame.transform` -4. `Applying Elementwise Functions`_: :meth:`~DataFrame.applymap` +4. `Applying Elementwise Functions`_: :meth:`~DataFrame.map` .. _basics.pipe: @@ -1170,7 +1170,7 @@ Applying elementwise functions ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Since not all functions can be vectorized (accept NumPy arrays and return -another array or value), the methods :meth:`~DataFrame.applymap` on DataFrame +another array or value), the methods :meth:`~DataFrame.map` on DataFrame and analogously :meth:`~Series.map` on Series accept any Python function taking a single value and returning a single value. For example: @@ -1187,7 +1187,7 @@ a single value and returning a single value. For example: return len(str(x)) df4["one"].map(f) - df4.applymap(f) + df4.map(f) :meth:`Series.map` has an additional feature; it can be used to easily "link" or "map" values defined by a secondary series. This is closely related diff --git a/doc/source/user_guide/cookbook.rst b/doc/source/user_guide/cookbook.rst index 8a01be6d55aa2..3eee4ce7ac25c 100644 --- a/doc/source/user_guide/cookbook.rst +++ b/doc/source/user_guide/cookbook.rst @@ -242,7 +242,7 @@ Ambiguity arises when an index consists of integers with a non-zero start or non New columns *********** -`Efficiently and dynamically creating new columns using applymap +`Efficiently and dynamically creating new columns using DataFrame.map (previously named applymap) `__ .. ipython:: python @@ -254,7 +254,7 @@ New columns new_cols = [str(x) + "_cat" for x in source_cols] categories = {1: "Alpha", 2: "Beta", 3: "Charlie"} - df[new_cols] = df[source_cols].applymap(categories.get) + df[new_cols] = df[source_cols].map(categories.get) df `Keep other columns when using min() with groupby diff --git a/doc/source/user_guide/style.ipynb b/doc/source/user_guide/style.ipynb index 79596c946c068..7ae19dfe8021e 100644 --- a/doc/source/user_guide/style.ipynb +++ b/doc/source/user_guide/style.ipynb @@ -352,7 +352,7 @@ "\n", "- 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", "- 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", - "- 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", + "- 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", "\n", "[table]: ../reference/api/pandas.io.formats.style.Styler.set_table_styles.rst\n", "[styler]: ../reference/api/pandas.io.formats.style.Styler.rst\n", @@ -362,7 +362,7 @@ "[applyindex]: ../reference/api/pandas.io.formats.style.Styler.apply_index.rst\n", "[applymapindex]: ../reference/api/pandas.io.formats.style.Styler.applymap_index.rst\n", "[dfapply]: ../reference/api/pandas.DataFrame.apply.rst\n", - "[dfapplymap]: ../reference/api/pandas.DataFrame.applymap.rst" + "[dfmap]: ../reference/api/pandas.DataFrame.map.rst" ] }, { diff --git a/doc/source/user_guide/visualization.rst b/doc/source/user_guide/visualization.rst index ae8de4d5386b1..a7d7a09a6bcc5 100644 --- a/doc/source/user_guide/visualization.rst +++ b/doc/source/user_guide/visualization.rst @@ -1709,7 +1709,7 @@ Colormaps can also be used other plot types, like bar charts: .. ipython:: python - dd = pd.DataFrame(np.random.randn(10, 10)).applymap(abs) + dd = pd.DataFrame(np.random.randn(10, 10)).map(abs) dd = dd.cumsum() plt.figure(); diff --git a/doc/source/whatsnew/v2.1.0.rst b/doc/source/whatsnew/v2.1.0.rst index 0772cadf6e737..c039613ddf8f8 100644 --- a/doc/source/whatsnew/v2.1.0.rst +++ b/doc/source/whatsnew/v2.1.0.rst @@ -25,7 +25,7 @@ enhancement1 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ When given a callable, :meth:`Series.map` applies the callable to all elements of the :class:`Series`. -Similarly, :meth:`DataFrame.applymap` applies the callable to all elements of the :class:`DataFrame`, +Similarly, :meth:`DataFrame.map` applies the callable to all elements of the :class:`DataFrame`, while :meth:`Index.map` applies the callable to all elements of the :class:`Index`. 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 ser = pd.Series(["a", "b", np.nan], dtype="category") ser.map(str.upper, na_action="ignore") df = pd.DataFrame(ser) - df.applymap(str.upper, na_action="ignore") + df.map(str.upper, na_action="ignore") idx = pd.Index(ser) idx.map(str.upper, na_action="ignore") +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`). + Also, note that :meth:`Categorical.map` implicitly has had its ``na_action`` set to ``"ignore"`` by default. This has been deprecated and will :meth:`Categorical.map` in the future change the default to ``na_action=None``, like for all the other array types. @@ -223,6 +225,7 @@ Deprecations - Deprecated :func:`is_datetime64tz_dtype`, check ``isinstance(dtype, pd.DatetimeTZDtype)`` instead (:issue:`52607`) - Deprecated :func:`is_int64_dtype`, check ``dtype == np.dtype(np.int64)`` instead (:issue:`52564`) - Deprecated :func:`is_interval_dtype`, check ``isinstance(dtype, pd.IntervalDtype)`` instead (:issue:`52607`) +- Deprecated :meth:`DataFrame.applymap`. Use the new :meth:`DataFrame.map` method instead (:issue:`52353`) - Deprecated :meth:`DataFrame.swapaxes` and :meth:`Series.swapaxes`, use :meth:`DataFrame.transpose` or :meth:`Series.transpose` instead (:issue:`51946`) - Deprecated ``freq`` parameter in :class:`PeriodArray` constructor, pass ``dtype`` instead (:issue:`52462`) - 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`) diff --git a/pandas/core/frame.py b/pandas/core/frame.py index 0e8f2b0044c66..5341b87c39676 100644 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -9673,7 +9673,7 @@ def apply( See Also -------- - DataFrame.applymap: For elementwise operations. + DataFrame.map: For elementwise operations. DataFrame.aggregate: Only perform aggregating type operations. DataFrame.transform: Only perform transforming type operations. @@ -9765,12 +9765,16 @@ def apply( ) return op.apply().__finalize__(self, method="apply") - def applymap( + def map( self, func: PythonFuncType, na_action: str | None = None, **kwargs ) -> DataFrame: """ Apply a function to a Dataframe elementwise. + .. versionadded:: 2.1.0 + + DataFrame.applymap was deprecated and renamed to DataFrame.map. + This method applies a function that accepts and returns a scalar to every element of a DataFrame. @@ -9798,6 +9802,7 @@ def applymap( -------- DataFrame.apply : Apply a function along input axis of DataFrame. DataFrame.replace: Replace values given in `to_replace` with `value`. + Series.map : Apply a function elementwise on a Series. Examples -------- @@ -9807,7 +9812,7 @@ def applymap( 0 1.000 2.120 1 3.356 4.567 - >>> df.applymap(lambda x: len(str(x))) + >>> df.map(lambda x: len(str(x))) 0 1 0 3 4 1 5 5 @@ -9816,7 +9821,7 @@ def applymap( >>> df_copy = df.copy() >>> df_copy.iloc[0, 0] = pd.NA - >>> df_copy.applymap(lambda x: len(str(x)), na_action='ignore') + >>> df_copy.map(lambda x: len(str(x)), na_action='ignore') 0 1 0 NaN 4 1 5.0 5 @@ -9824,12 +9829,12 @@ def applymap( Note that a vectorized version of `func` often exists, which will be much faster. You could square each number elementwise. - >>> df.applymap(lambda x: x**2) + >>> df.map(lambda x: x**2) 0 1 0 1.000000 4.494400 1 11.262736 20.857489 - But it's better to avoid applymap in that case. + But it's better to avoid map in that case. >>> df ** 2 0 1 @@ -9849,7 +9854,61 @@ def applymap( def infer(x): return x._map_values(func, na_action=na_action) - return self.apply(infer).__finalize__(self, "applymap") + return self.apply(infer).__finalize__(self, "map") + + def applymap( + self, func: PythonFuncType, na_action: str | None = None, **kwargs + ) -> DataFrame: + """ + Apply a function to a Dataframe elementwise. + + .. deprecated:: 2.1.0 + + DataFrame.applymap has been deprecated. Use DataFrame.map instead. + + This method applies a function that accepts and returns a scalar + to every element of a DataFrame. + + Parameters + ---------- + func : callable + 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`. + + Returns + ------- + DataFrame + Transformed DataFrame. + + See Also + -------- + DataFrame.apply : Apply a function along input axis of DataFrame. + DataFrame.map : Apply a function along input axis of DataFrame. + DataFrame.replace: Replace values given in `to_replace` with `value`. + + Examples + -------- + >>> df = pd.DataFrame([[1, 2.12], [3.356, 4.567]]) + >>> df + 0 1 + 0 1.000 2.120 + 1 3.356 4.567 + + >>> df.map(lambda x: len(str(x))) + 0 1 + 0 3 4 + 1 5 5 + """ + warnings.warn( + "DataFrame.applymap has been deprecated. Use DataFrame.map instead.", + FutureWarning, + stacklevel=find_stack_level(), + ) + return self.map(func, na_action=na_action, **kwargs) # ---------------------------------------------------------------------- # Merging / joining methods diff --git a/pandas/core/generic.py b/pandas/core/generic.py index 492fcff5c4f87..9a1ba12482570 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -5942,7 +5942,7 @@ def pipe( See Also -------- DataFrame.apply : Apply a function along input axis of DataFrame. - DataFrame.applymap : Apply a function elementwise on a whole DataFrame. + DataFrame.map : Apply a function elementwise on a whole DataFrame. Series.map : Apply a mapping correspondence on a :class:`~pandas.Series`. diff --git a/pandas/core/series.py b/pandas/core/series.py index a9d63c5d03bf8..6f8cce2499c3d 100644 --- a/pandas/core/series.py +++ b/pandas/core/series.py @@ -4250,7 +4250,7 @@ def map( Series.apply : For applying more complex functions on a Series. Series.replace: Replace values given in `to_replace` with `value`. DataFrame.apply : Apply a function row-/column-wise. - DataFrame.applymap : Apply a function elementwise on a whole DataFrame. + DataFrame.map : Apply a function elementwise on a whole DataFrame. Notes ----- diff --git a/pandas/core/shared_docs.py b/pandas/core/shared_docs.py index 6fbc8748c178d..410fa8a3312a9 100644 --- a/pandas/core/shared_docs.py +++ b/pandas/core/shared_docs.py @@ -609,7 +609,7 @@ DataFrame.fillna : Fill NA values. Series.where : Replace values based on boolean condition. DataFrame.where : Replace values based on boolean condition. - DataFrame.applymap: Apply a function to a Dataframe elementwise. + DataFrame.map: Apply a function to a Dataframe elementwise. Series.map: Map values of Series according to an input mapping or function. Series.str.replace : Simple string replacement. diff --git a/pandas/io/formats/style.py b/pandas/io/formats/style.py index 26ec4844d2a75..e2c5ed2ea92b6 100644 --- a/pandas/io/formats/style.py +++ b/pandas/io/formats/style.py @@ -1813,7 +1813,7 @@ def _apply_index( if method == "apply": result = data.apply(func, axis=0, **kwargs) elif method == "applymap": - result = data.applymap(func, **kwargs) + result = data.map(func, **kwargs) self._update_ctx_header(result, axis) return self @@ -1938,7 +1938,7 @@ def _applymap( if subset is None: subset = IndexSlice[:] subset = non_reducing_slice(subset) - result = self.data.loc[subset].applymap(func) + result = self.data.loc[subset].map(func) self._update_ctx(result) return self diff --git a/pandas/io/json/_json.py b/pandas/io/json/_json.py index ef8c7550476e3..f73d372a920a8 100644 --- a/pandas/io/json/_json.py +++ b/pandas/io/json/_json.py @@ -365,7 +365,7 @@ def __init__( obj = obj.copy() timedeltas = obj.select_dtypes(include=["timedelta"]).columns if len(timedeltas): - obj[timedeltas] = obj[timedeltas].applymap(lambda x: x.isoformat()) + obj[timedeltas] = obj[timedeltas].map(lambda x: x.isoformat()) # Convert PeriodIndex to datetimes before serializing if isinstance(obj.index.dtype, PeriodDtype): obj.index = obj.index.to_timestamp() diff --git a/pandas/tests/frame/methods/test_map.py b/pandas/tests/frame/methods/test_map.py index 0dac96cda9b54..596ef453b2e02 100644 --- a/pandas/tests/frame/methods/test_map.py +++ b/pandas/tests/frame/methods/test_map.py @@ -13,26 +13,26 @@ import pandas._testing as tm -def test_applymap(float_frame): - result = float_frame.applymap(lambda x: x * 2) +def test_map(float_frame): + result = float_frame.map(lambda x: x * 2) tm.assert_frame_equal(result, float_frame * 2) - float_frame.applymap(type) + float_frame.map(type) # GH 465: function returning tuples - result = float_frame.applymap(lambda x: (x, x))["A"][0] + result = float_frame.map(lambda x: (x, x))["A"][0] assert isinstance(result, tuple) @pytest.mark.parametrize("val", [1, 1.0]) -def test_applymap_float_object_conversion(val): +def test_map_float_object_conversion(val): # GH 2909: object conversion to float in constructor? df = DataFrame(data=[val, "a"]) - result = df.applymap(lambda x: x).dtypes[0] + result = df.map(lambda x: x).dtypes[0] assert result == object @pytest.mark.parametrize("na_action", [None, "ignore"]) -def test_applymap_keeps_dtype(na_action): +def test_map_keeps_dtype(na_action): # GH52219 arr = Series(["a", np.nan, "b"]) sparse_arr = arr.astype(pd.SparseDtype(object)) @@ -41,7 +41,7 @@ def test_applymap_keeps_dtype(na_action): def func(x): return str.upper(x) if not pd.isna(x) else x - result = df.applymap(func, na_action=na_action) + result = df.map(func, na_action=na_action) expected_sparse = pd.array(["A", np.nan, "B"], dtype=pd.SparseDtype(object)) expected_arr = expected_sparse.astype(object) @@ -49,21 +49,21 @@ def func(x): tm.assert_frame_equal(result, expected) - result_empty = df.iloc[:0, :].applymap(func, na_action=na_action) + result_empty = df.iloc[:0, :].map(func, na_action=na_action) expected_empty = expected.iloc[:0, :] tm.assert_frame_equal(result_empty, expected_empty) -def test_applymap_str(): +def test_map_str(): # GH 2786 df = DataFrame(np.random.random((3, 4))) df2 = df.copy() cols = ["a", "a", "a", "a"] df.columns = cols - expected = df2.applymap(str) + expected = df2.map(str) expected.columns = cols - result = df.applymap(str) + result = df.map(str) tm.assert_frame_equal(result, expected) @@ -71,11 +71,11 @@ def test_applymap_str(): "col, val", [["datetime", Timestamp("20130101")], ["timedelta", pd.Timedelta("1 min")]], ) -def test_applymap_datetimelike(col, val): +def test_map_datetimelike(col, val): # datetime/timedelta df = DataFrame(np.random.random((3, 4))) df[col] = val - result = df.applymap(str) + result = df.map(str) assert result.loc[0, col] == str(df.loc[0, col]) @@ -89,26 +89,26 @@ def test_applymap_datetimelike(col, val): ], ) @pytest.mark.parametrize("func", [round, lambda x: x]) -def test_applymap_empty(expected, func): +def test_map_empty(expected, func): # GH 8222 - result = expected.applymap(func) + result = expected.map(func) tm.assert_frame_equal(result, expected) -def test_applymap_kwargs(): +def test_map_kwargs(): # GH 40652 - result = DataFrame([[1, 2], [3, 4]]).applymap(lambda x, y: x + y, y=2) + result = DataFrame([[1, 2], [3, 4]]).map(lambda x, y: x + y, y=2) expected = DataFrame([[3, 4], [5, 6]]) tm.assert_frame_equal(result, expected) -def test_applymap_na_ignore(float_frame): +def test_map_na_ignore(float_frame): # GH 23803 - strlen_frame = float_frame.applymap(lambda x: len(str(x))) + strlen_frame = float_frame.map(lambda x: len(str(x))) float_frame_with_na = float_frame.copy() mask = np.random.randint(0, 2, size=float_frame.shape, dtype=bool) float_frame_with_na[mask] = pd.NA - strlen_frame_na_ignore = float_frame_with_na.applymap( + strlen_frame_na_ignore = float_frame_with_na.map( lambda x: len(str(x)), na_action="ignore" ) strlen_frame_with_na = strlen_frame.copy() @@ -116,7 +116,7 @@ def test_applymap_na_ignore(float_frame): tm.assert_frame_equal(strlen_frame_na_ignore, strlen_frame_with_na) -def test_applymap_box_timestamps(): +def test_map_box_timestamps(): # GH 2689, GH 2627 ser = Series(date_range("1/1/2000", periods=10)) @@ -124,10 +124,10 @@ def func(x): return (x.hour, x.day, x.month) # it works! - DataFrame(ser).applymap(func) + DataFrame(ser).map(func) -def test_applymap_box(): +def test_map_box(): # ufunc will not be boxed. Same test cases as the test_map_box df = DataFrame( { @@ -144,7 +144,7 @@ def test_applymap_box(): } ) - result = df.applymap(lambda x: type(x).__name__) + result = df.map(lambda x: type(x).__name__) expected = DataFrame( { "a": ["Timestamp", "Timestamp"], @@ -156,19 +156,19 @@ def test_applymap_box(): tm.assert_frame_equal(result, expected) -def test_frame_applymap_dont_convert_datetime64(): +def test_frame_map_dont_convert_datetime64(): from pandas.tseries.offsets import BDay df = DataFrame({"x1": [datetime(1996, 1, 1)]}) - df = df.applymap(lambda x: x + BDay()) - df = df.applymap(lambda x: x + BDay()) + df = df.map(lambda x: x + BDay()) + df = df.map(lambda x: x + BDay()) result = df.x1.dtype assert result == "M8[ns]" -def test_applymap_function_runs_once(): +def test_map_function_runs_once(): df = DataFrame({"a": [1, 2, 3]}) values = [] # Save values function is applied to @@ -182,18 +182,18 @@ def non_reducing_function(val): for func in [reducing_function, non_reducing_function]: del values[:] - df.applymap(func) + df.map(func) assert values == df.a.to_list() -def test_applymap_type(): +def test_map_type(): # GH 46719 df = DataFrame( {"col1": [3, "string", float], "col2": [0.25, datetime(2020, 1, 1), np.nan]}, index=["a", "b", "c"], ) - result = df.applymap(type) + result = df.map(type) expected = DataFrame( {"col1": [int, str, type], "col2": [float, datetime, float]}, index=["a", "b", "c"], @@ -201,7 +201,15 @@ def test_applymap_type(): tm.assert_frame_equal(result, expected) -def test_applymap_invalid_na_action(float_frame): +def test_map_invalid_na_action(float_frame): # GH 23803 with pytest.raises(ValueError, match="na_action must be .*Got 'abc'"): - float_frame.applymap(lambda x: len(str(x)), na_action="abc") + float_frame.map(lambda x: len(str(x)), na_action="abc") + + +def test_applymap_deprecated(): + # GH52353 + df = DataFrame({"a": [1, 2, 3]}) + msg = "DataFrame.applymap has been deprecated. Use DataFrame.map instead." + with tm.assert_produces_warning(FutureWarning, match=msg): + df.applymap(lambda x: x) diff --git a/pandas/tests/frame/methods/test_to_csv.py b/pandas/tests/frame/methods/test_to_csv.py index 8a68876d7e11a..639c6f9d73511 100644 --- a/pandas/tests/frame/methods/test_to_csv.py +++ b/pandas/tests/frame/methods/test_to_csv.py @@ -997,9 +997,7 @@ def test_to_csv_date_format(self, datetime_frame): # Check that the data was put in the specified format test = read_csv(path, index_col=0) - datetime_frame_int = datetime_frame.applymap( - lambda x: int(x.strftime("%Y%m%d")) - ) + datetime_frame_int = datetime_frame.map(lambda x: int(x.strftime("%Y%m%d"))) datetime_frame_int.index = datetime_frame_int.index.map( lambda x: int(x.strftime("%Y%m%d")) ) @@ -1010,9 +1008,7 @@ def test_to_csv_date_format(self, datetime_frame): # Check that the data was put in the specified format test = read_csv(path, index_col=0) - datetime_frame_str = datetime_frame.applymap( - lambda x: x.strftime("%Y-%m-%d") - ) + datetime_frame_str = datetime_frame.map(lambda x: x.strftime("%Y-%m-%d")) datetime_frame_str.index = datetime_frame_str.index.map( lambda x: x.strftime("%Y-%m-%d") ) @@ -1025,7 +1021,7 @@ def test_to_csv_date_format(self, datetime_frame): test = read_csv(path, index_col=0) - datetime_frame_columns = datetime_frame_columns.applymap( + datetime_frame_columns = datetime_frame_columns.map( lambda x: int(x.strftime("%Y%m%d")) ) # Columns don't get converted to ints by read_csv diff --git a/pandas/tests/generic/test_finalize.py b/pandas/tests/generic/test_finalize.py index cdab112e7ad86..3c4ea5bd1fb2c 100644 --- a/pandas/tests/generic/test_finalize.py +++ b/pandas/tests/generic/test_finalize.py @@ -158,9 +158,7 @@ ({"A": ["a", "b", "c"], "B": [1, 3, 5], "C": [2, 4, 6]},), operator.methodcaller("melt", id_vars=["A"], value_vars=["B"]), ), - pytest.param( - (pd.DataFrame, frame_data, operator.methodcaller("applymap", lambda x: x)) - ), + pytest.param((pd.DataFrame, frame_data, operator.methodcaller("map", lambda x: x))), pytest.param( ( pd.DataFrame, diff --git a/pandas/tests/io/sas/test_sas7bdat.py b/pandas/tests/io/sas/test_sas7bdat.py index 348d2382976c3..d56139d32b1da 100644 --- a/pandas/tests/io/sas/test_sas7bdat.py +++ b/pandas/tests/io/sas/test_sas7bdat.py @@ -266,12 +266,12 @@ def test_max_sas_date(datapath): df = pd.read_sas(fname, encoding="iso-8859-1") # SAS likes to left pad strings with spaces - lstrip before comparing - df = df.applymap(lambda x: x.lstrip() if isinstance(x, str) else x) + df = df.map(lambda x: x.lstrip() if isinstance(x, str) else x) # GH 19732: Timestamps imported from sas will incur floating point errors try: df["dt_as_dt"] = df["dt_as_dt"].dt.round("us") except pd._libs.tslibs.np_datetime.OutOfBoundsDatetime: - df = df.applymap(round_datetime_to_ms) + df = df.map(round_datetime_to_ms) except AttributeError: df["dt_as_dt"] = df["dt_as_dt"].apply(round_datetime_to_ms) # if there are any date/times > pandas.Timestamp.max then ALL in that chunk @@ -302,12 +302,12 @@ def test_max_sas_date_iterator(datapath): results = [] for df in pd.read_sas(fname, encoding="iso-8859-1", chunksize=1): # SAS likes to left pad strings with spaces - lstrip before comparing - df = df.applymap(lambda x: x.lstrip() if isinstance(x, str) else x) + df = df.map(lambda x: x.lstrip() if isinstance(x, str) else x) # GH 19732: Timestamps imported from sas will incur floating point errors try: df["dt_as_dt"] = df["dt_as_dt"].dt.round("us") except pd._libs.tslibs.np_datetime.OutOfBoundsDatetime: - df = df.applymap(round_datetime_to_ms) + df = df.map(round_datetime_to_ms) except AttributeError: df["dt_as_dt"] = df["dt_as_dt"].apply(round_datetime_to_ms) df.reset_index(inplace=True, drop=True) diff --git a/pandas/tests/io/test_html.py b/pandas/tests/io/test_html.py index 047918d4694e0..4bd4e0cd7146f 100644 --- a/pandas/tests/io/test_html.py +++ b/pandas/tests/io/test_html.py @@ -131,7 +131,7 @@ def test_to_html_compat(self): r_idx_names=False, ) # pylint: disable-next=consider-using-f-string - .applymap("{:.3f}".format).astype(float) + .map("{:.3f}".format).astype(float) ) out = df.to_html() res = self.read_html(out, attrs={"class": "dataframe"}, index_col=0)[0] @@ -682,8 +682,8 @@ def try_remove_ws(x): "Hamilton Bank, NA", "The Citizens Savings Bank", ] - dfnew = df.applymap(try_remove_ws).replace(old, new) - gtnew = ground_truth.applymap(try_remove_ws) + dfnew = df.map(try_remove_ws).replace(old, new) + gtnew = ground_truth.map(try_remove_ws) converted = dfnew date_cols = ["Closing Date", "Updated Date"] converted[date_cols] = converted[date_cols].apply(to_datetime) diff --git a/pandas/tests/io/test_sql.py b/pandas/tests/io/test_sql.py index d0b7492f8d9ba..4a12ef1fa240b 100644 --- a/pandas/tests/io/test_sql.py +++ b/pandas/tests/io/test_sql.py @@ -2135,13 +2135,13 @@ def test_datetime_time(self, sqlite_buildin): sqlite_conn = sqlite_buildin assert sql.to_sql(df, "test_time2", sqlite_conn, index=False) == 2 res = sql.read_sql_query("SELECT * FROM test_time2", sqlite_conn) - ref = df.applymap(lambda _: _.strftime("%H:%M:%S.%f")) + ref = df.map(lambda _: _.strftime("%H:%M:%S.%f")) tm.assert_frame_equal(ref, res) # check if adapter is in place # then test if sqlalchemy is unaffected by the sqlite adapter assert sql.to_sql(df, "test_time3", self.conn, index=False) == 2 if self.flavor == "sqlite": res = sql.read_sql_query("SELECT * FROM test_time3", self.conn) - ref = df.applymap(lambda _: _.strftime("%H:%M:%S.%f")) + ref = df.map(lambda _: _.strftime("%H:%M:%S.%f")) tm.assert_frame_equal(ref, res) res = sql.read_sql_table("test_time3", self.conn) tm.assert_frame_equal(df, res) @@ -2949,7 +2949,7 @@ def test_datetime_time(self, tz_aware): res = read_sql_query("SELECT * FROM test_time", self.conn) if self.flavor == "sqlite": # comes back as strings - expected = df.applymap(lambda _: _.strftime("%H:%M:%S.%f")) + expected = df.map(lambda _: _.strftime("%H:%M:%S.%f")) tm.assert_frame_equal(res, expected) def _get_index_columns(self, tbl_name):