From 4de8d75ffa5c157c68a9d45c5698d618ff35d5b1 Mon Sep 17 00:00:00 2001 From: dannyi96 Date: Mon, 15 Aug 2022 17:21:46 +0530 Subject: [PATCH 01/15] Add axis parameter to add_prefix and add_suffix --- pandas/core/generic.py | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/pandas/core/generic.py b/pandas/core/generic.py index 8096b57168d8c..da767e4064507 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -4556,7 +4556,7 @@ def _update_inplace(self, result, verify_is_copy: bool_t = True) -> None: self._maybe_update_cacher(verify_is_copy=verify_is_copy, inplace=True) @final - def add_prefix(self: NDFrameT, prefix: str, copy: bool_t = True) -> NDFrameT: + def add_prefix(self: NDFrameT, prefix: str, copy: bool_t = True, axis: Axis = None) -> NDFrameT: """ Prefix labels with string `prefix`. @@ -4615,8 +4615,12 @@ def add_prefix(self: NDFrameT, prefix: str, copy: bool_t = True) -> NDFrameT: 3 4 6 """ f = functools.partial("{prefix}{}".format, prefix=prefix) - - mapper = {self._info_axis_name: f} + + axis_name = self._info_axis_name + if axis is not None: + axis_name = self._get_axis_name(axis) + + mapper = {axis_name: f} # error: Incompatible return value type (got "Optional[NDFrameT]", # expected "NDFrameT") # error: Argument 1 to "rename" of "NDFrame" has incompatible type @@ -4624,7 +4628,7 @@ def add_prefix(self: NDFrameT, prefix: str, copy: bool_t = True) -> NDFrameT: return self._rename(**mapper, copy=copy) # type: ignore[return-value, arg-type] @final - def add_suffix(self: NDFrameT, suffix: str, copy: bool_t = True) -> NDFrameT: + def add_suffix(self: NDFrameT, suffix: str, copy: bool_t = True, axis: Axis = None) -> NDFrameT: """ Suffix labels with string `suffix`. @@ -4683,8 +4687,12 @@ def add_suffix(self: NDFrameT, suffix: str, copy: bool_t = True) -> NDFrameT: 3 4 6 """ f = functools.partial("{}{suffix}".format, suffix=suffix) - - mapper = {self._info_axis_name: f} + + axis_name = self._info_axis_name + if axis is not None: + axis_name = self._get_axis_name(axis) + + mapper = {axis_name: f} # error: Incompatible return value type (got "Optional[NDFrameT]", # expected "NDFrameT") # error: Argument 1 to "rename" of "NDFrame" has incompatible type From d7ca73959e109176d60ef62989a7f544989ca7fe Mon Sep 17 00:00:00 2001 From: dannyi96 Date: Mon, 15 Aug 2022 17:25:27 +0530 Subject: [PATCH 02/15] Add axis parameter to add_prefix and add_suffix --- pandas/core/generic.py | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/pandas/core/generic.py b/pandas/core/generic.py index da767e4064507..7f16ecff241d4 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -4556,7 +4556,9 @@ def _update_inplace(self, result, verify_is_copy: bool_t = True) -> None: self._maybe_update_cacher(verify_is_copy=verify_is_copy, inplace=True) @final - def add_prefix(self: NDFrameT, prefix: str, copy: bool_t = True, axis: Axis = None) -> NDFrameT: + def add_prefix( + self: NDFrameT, prefix: str, copy: bool_t = True, axis: Axis = None + ) -> NDFrameT: """ Prefix labels with string `prefix`. @@ -4615,11 +4617,11 @@ def add_prefix(self: NDFrameT, prefix: str, copy: bool_t = True, axis: Axis = No 3 4 6 """ f = functools.partial("{prefix}{}".format, prefix=prefix) - - axis_name = self._info_axis_name + + axis_name = self._info_axis_name if axis is not None: axis_name = self._get_axis_name(axis) - + mapper = {axis_name: f} # error: Incompatible return value type (got "Optional[NDFrameT]", # expected "NDFrameT") @@ -4628,7 +4630,9 @@ def add_prefix(self: NDFrameT, prefix: str, copy: bool_t = True, axis: Axis = No return self._rename(**mapper, copy=copy) # type: ignore[return-value, arg-type] @final - def add_suffix(self: NDFrameT, suffix: str, copy: bool_t = True, axis: Axis = None) -> NDFrameT: + def add_suffix( + self: NDFrameT, suffix: str, copy: bool_t = True, axis: Axis = None + ) -> NDFrameT: """ Suffix labels with string `suffix`. @@ -4687,11 +4691,11 @@ def add_suffix(self: NDFrameT, suffix: str, copy: bool_t = True, axis: Axis = No 3 4 6 """ f = functools.partial("{}{suffix}".format, suffix=suffix) - - axis_name = self._info_axis_name + + axis_name = self._info_axis_name if axis is not None: axis_name = self._get_axis_name(axis) - + mapper = {axis_name: f} # error: Incompatible return value type (got "Optional[NDFrameT]", # expected "NDFrameT") From e5a031010cae257fb6a4957c2cfd76d27fd6d170 Mon Sep 17 00:00:00 2001 From: dannyi96 Date: Mon, 15 Aug 2022 17:41:27 +0530 Subject: [PATCH 03/15] Added testcases --- .../frame/methods/test_add_prefix_suffix.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/pandas/tests/frame/methods/test_add_prefix_suffix.py b/pandas/tests/frame/methods/test_add_prefix_suffix.py index cc36a3caf6ec7..57ec1c18089ec 100644 --- a/pandas/tests/frame/methods/test_add_prefix_suffix.py +++ b/pandas/tests/frame/methods/test_add_prefix_suffix.py @@ -71,3 +71,22 @@ def test_add_prefix_suffix_copy(float_frame): ser_with_suffix = ser.add_suffix("#foo", copy=False) tm.assert_index_equal(ser_with_suffix.index, expected) assert tm.shares_memory(ser_with_suffix, ser) + + +def test_add_prefix_suffix_axis(float_frame): + # GH 47819 + with_prefix = float_frame.add_prefix("foo#", axis=0) + expected = Index([f"foo#{c}" for c in float_frame.index]) + tm.assert_index_equal(with_prefix.index, expected) + + with_prefix = float_frame.add_prefix("foo#", axis=1) + expected = Index([f"foo#{c}" for c in float_frame.columns]) + tm.assert_index_equal(with_prefix.columns, expected) + + with_pct_suffix = float_frame.add_suffix("#foo", axis=0) + expected = Index([f"{c}#foo" for c in float_frame.index]) + tm.assert_index_equal(with_pct_suffix.index, expected) + + with_pct_suffix = float_frame.add_suffix("#foo", axis=1) + expected = Index([f"{c}#foo" for c in float_frame.columns]) + tm.assert_index_equal(with_pct_suffix.columns, expected) From 802346aaa0aaee07157c15d753825824ca60d084 Mon Sep 17 00:00:00 2001 From: dannyi96 Date: Mon, 15 Aug 2022 17:47:31 +0530 Subject: [PATCH 04/15] docstring update --- pandas/core/generic.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pandas/core/generic.py b/pandas/core/generic.py index 7f16ecff241d4..91f0d60189d2c 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -4571,6 +4571,8 @@ def add_prefix( The string to add before each label. copy : bool, default True Whether to copy the underlying data. + axis : {{0 or 'index', 1 or 'columns', None}}, default None + Axis to add prefix on .. versionadded:: 1.5.0 @@ -4645,6 +4647,8 @@ def add_suffix( The string to add after each label. copy : bool, default True Whether to copy the underlying data. + axis : {{0 or 'index', 1 or 'columns', None}}, default None + Axis to add suffix on .. versionadded:: 1.5.0 From 74eb3d891fb7d0be450eea14d53a78647b5d3b2f Mon Sep 17 00:00:00 2001 From: dannyi96 Date: Mon, 15 Aug 2022 18:36:27 +0530 Subject: [PATCH 05/15] docstring update --- pandas/core/generic.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pandas/core/generic.py b/pandas/core/generic.py index 91f0d60189d2c..e537a35978c82 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -4557,7 +4557,7 @@ def _update_inplace(self, result, verify_is_copy: bool_t = True) -> None: @final def add_prefix( - self: NDFrameT, prefix: str, copy: bool_t = True, axis: Axis = None + self: NDFrameT, prefix: str, copy: bool_t = True, axis: Axis | None = None ) -> NDFrameT: """ Prefix labels with string `prefix`. @@ -4633,7 +4633,7 @@ def add_prefix( @final def add_suffix( - self: NDFrameT, suffix: str, copy: bool_t = True, axis: Axis = None + self: NDFrameT, suffix: str, copy: bool_t = True, axis: Axis | None = None ) -> NDFrameT: """ Suffix labels with string `suffix`. From d83b0ea9e25cfba41e5d6db8e15b4f2062c0ca20 Mon Sep 17 00:00:00 2001 From: dannyi96 Date: Sat, 20 Aug 2022 02:48:42 +0530 Subject: [PATCH 06/15] updated whatsnew file --- doc/source/whatsnew/v1.5.0.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/source/whatsnew/v1.5.0.rst b/doc/source/whatsnew/v1.5.0.rst index b71d294b97f9a..6f45d3c2c4e96 100644 --- a/doc/source/whatsnew/v1.5.0.rst +++ b/doc/source/whatsnew/v1.5.0.rst @@ -294,7 +294,7 @@ Other enhancements - :meth:`DataFrame.compare` now accepts an argument ``result_names`` to allow the user to specify the result's names of both left and right DataFrame which are being compared. This is by default ``'self'`` and ``'other'`` (:issue:`44354`) - :meth:`Series.add_suffix`, :meth:`DataFrame.add_suffix`, :meth:`Series.add_prefix` and :meth:`DataFrame.add_prefix` support a ``copy`` argument. If ``False``, the underlying data is not copied in the returned object (:issue:`47934`) - :meth:`DataFrame.set_index` now supports a ``copy`` keyword. If ``False``, the underlying data is not copied when a new :class:`DataFrame` is returned (:issue:`48043`) - +- :meth:`Series.add_suffix`, :meth:`DataFrame.add_suffix`, :meth:`Series.add_prefix` and :meth:`DataFrame.add_prefix` support an ``axis`` argument. If ``axis`` is unset, rows are considered for ``Series`` and columns for ``DataFrame``. If ``axis`` is set, this default behaviour can be overwritten (:issue:`48085`) .. --------------------------------------------------------------------------- .. _whatsnew_150.notable_bug_fixes: From db2095ab6b6608a61a989df218abea18e7274000 Mon Sep 17 00:00:00 2001 From: dannyi96 Date: Sat, 20 Aug 2022 03:15:47 +0530 Subject: [PATCH 07/15] updated whatsnew file --- doc/source/whatsnew/v1.5.0.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/source/whatsnew/v1.5.0.rst b/doc/source/whatsnew/v1.5.0.rst index e3dc678a5ca63..cb8e381a11eaa 100644 --- a/doc/source/whatsnew/v1.5.0.rst +++ b/doc/source/whatsnew/v1.5.0.rst @@ -334,7 +334,7 @@ Other enhancements - :meth:`Series.add_suffix`, :meth:`DataFrame.add_suffix`, :meth:`Series.add_prefix` and :meth:`DataFrame.add_prefix` support a ``copy`` argument. If ``False``, the underlying data is not copied in the returned object (:issue:`47934`) - :meth:`DataFrame.set_index` now supports a ``copy`` keyword. If ``False``, the underlying data is not copied when a new :class:`DataFrame` is returned (:issue:`48043`) - The method :meth:`.ExtensionArray.factorize` accepts ``use_na_sentinel=False`` for determining how null values are to be treated (:issue:`46601`) -- :meth:`Series.add_suffix`, :meth:`DataFrame.add_suffix`, :meth:`Series.add_prefix` and :meth:`DataFrame.add_prefix` support an ``axis`` argument. If ``axis`` is unset, rows are considered for ``Series`` and columns for ``DataFrame``. If ``axis`` is set, this default behaviour can be overwritten (:issue:`48085`) +- :meth:`Series.add_suffix`, :meth:`DataFrame.add_suffix`, :meth:`Series.add_prefix` and :meth:`DataFrame.add_prefix` support an ``axis`` argument. If ``axis`` is set, the default behaviour of which axis to consider can be overwritten (:issue:`48085`) .. --------------------------------------------------------------------------- .. _whatsnew_150.notable_bug_fixes: From c7106050f01a743800babe61b129750cfb87c502 Mon Sep 17 00:00:00 2001 From: dannyi96 Date: Sat, 20 Aug 2022 03:48:51 +0530 Subject: [PATCH 08/15] updated whatsnew file --- doc/source/whatsnew/v1.5.0.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/source/whatsnew/v1.5.0.rst b/doc/source/whatsnew/v1.5.0.rst index cb8e381a11eaa..f4c61f3429573 100644 --- a/doc/source/whatsnew/v1.5.0.rst +++ b/doc/source/whatsnew/v1.5.0.rst @@ -335,6 +335,7 @@ Other enhancements - :meth:`DataFrame.set_index` now supports a ``copy`` keyword. If ``False``, the underlying data is not copied when a new :class:`DataFrame` is returned (:issue:`48043`) - The method :meth:`.ExtensionArray.factorize` accepts ``use_na_sentinel=False`` for determining how null values are to be treated (:issue:`46601`) - :meth:`Series.add_suffix`, :meth:`DataFrame.add_suffix`, :meth:`Series.add_prefix` and :meth:`DataFrame.add_prefix` support an ``axis`` argument. If ``axis`` is set, the default behaviour of which axis to consider can be overwritten (:issue:`48085`) + .. --------------------------------------------------------------------------- .. _whatsnew_150.notable_bug_fixes: From eb218b4dc359492f680c7adc76b6ae799129aab4 Mon Sep 17 00:00:00 2001 From: dannyi96 Date: Sat, 20 Aug 2022 23:01:06 +0530 Subject: [PATCH 09/15] review comments --- doc/source/whatsnew/v1.5.0.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/source/whatsnew/v1.5.0.rst b/doc/source/whatsnew/v1.5.0.rst index 61c7940826521..4ad083563302a 100644 --- a/doc/source/whatsnew/v1.5.0.rst +++ b/doc/source/whatsnew/v1.5.0.rst @@ -334,7 +334,7 @@ Other enhancements - :meth:`Series.add_suffix`, :meth:`DataFrame.add_suffix`, :meth:`Series.add_prefix` and :meth:`DataFrame.add_prefix` support a ``copy`` argument. If ``False``, the underlying data is not copied in the returned object (:issue:`47934`) - :meth:`DataFrame.set_index` now supports a ``copy`` keyword. If ``False``, the underlying data is not copied when a new :class:`DataFrame` is returned (:issue:`48043`) - The method :meth:`.ExtensionArray.factorize` accepts ``use_na_sentinel=False`` for determining how null values are to be treated (:issue:`46601`) -- :meth:`Series.add_suffix`, :meth:`DataFrame.add_suffix`, :meth:`Series.add_prefix` and :meth:`DataFrame.add_prefix` support an ``axis`` argument. If ``axis`` is set, the default behaviour of which axis to consider can be overwritten (:issue:`48085`) +- :meth:`Series.add_suffix`, :meth:`DataFrame.add_suffix`, :meth:`Series.add_prefix` and :meth:`DataFrame.add_prefix` support an ``axis`` argument. If ``axis`` is set, the default behaviour of which axis to consider can be overwritten (:issue:`47819`) .. --------------------------------------------------------------------------- .. _whatsnew_150.notable_bug_fixes: From afaab36b7c1cc13459fea738f4e48e8ffacc4578 Mon Sep 17 00:00:00 2001 From: dannyi96 Date: Tue, 23 Aug 2022 15:48:16 +0530 Subject: [PATCH 10/15] address merge conflixts --- pandas/core/generic.py | 8 +-- .../frame/methods/test_add_prefix_suffix.py | 54 ------------------- 2 files changed, 2 insertions(+), 60 deletions(-) diff --git a/pandas/core/generic.py b/pandas/core/generic.py index 8eeb0b2b77bab..e53b81e9d31e0 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -4620,7 +4620,7 @@ def _update_inplace(self, result, verify_is_copy: bool_t = True) -> None: @final def add_prefix( - self: NDFrameT, prefix: str, copy: bool_t = True, axis: Axis | None = None + self: NDFrameT, prefix: str, axis: Axis | None = None ) -> NDFrameT: """ Prefix labels with string `prefix`. @@ -4632,8 +4632,6 @@ def add_prefix( ---------- prefix : str The string to add before each label. - copy : bool, default True - Whether to copy the underlying data. axis : {{0 or 'index', 1 or 'columns', None}}, default None Axis to add prefix on @@ -4696,7 +4694,7 @@ def add_prefix( @final def add_suffix( - self: NDFrameT, suffix: str, copy: bool_t = True, axis: Axis | None = None + self: NDFrameT, suffix: str, axis: Axis | None = None ) -> NDFrameT: """ Suffix labels with string `suffix`. @@ -4708,8 +4706,6 @@ def add_suffix( ---------- suffix : str The string to add after each label. - copy : bool, default True - Whether to copy the underlying data. axis : {{0 or 'index', 1 or 'columns', None}}, default None Axis to add suffix on diff --git a/pandas/tests/frame/methods/test_add_prefix_suffix.py b/pandas/tests/frame/methods/test_add_prefix_suffix.py index f0c2099d11c31..725a8088fbfa0 100644 --- a/pandas/tests/frame/methods/test_add_prefix_suffix.py +++ b/pandas/tests/frame/methods/test_add_prefix_suffix.py @@ -20,59 +20,6 @@ def test_add_prefix_suffix(float_frame): tm.assert_index_equal(with_pct_suffix.columns, expected) -def test_add_prefix_suffix_copy(float_frame): - # GH#47934 - ser = float_frame.iloc[0] - - with_prefix = float_frame.add_prefix("foo#", copy=True) - expected = Index([f"foo#{c}" for c in float_frame.columns]) - tm.assert_index_equal(with_prefix.columns, expected) - assert not any( - tm.shares_memory(float_frame.iloc[:, i], with_prefix.iloc[:, i]) - for i in range(float_frame.shape[1]) - ) - - ser_with_prefix = ser.add_prefix("foo#", copy=True) - tm.assert_index_equal(ser_with_prefix.index, expected) - assert not tm.shares_memory(ser_with_prefix, ser) - - with_prefix = float_frame.add_prefix("foo#", copy=False) - expected = Index([f"foo#{c}" for c in float_frame.columns]) - tm.assert_index_equal(with_prefix.columns, expected) - assert all( - tm.shares_memory(float_frame.iloc[:, i], with_prefix.iloc[:, i]) - for i in range(float_frame.shape[1]) - ) - - ser_with_prefix = ser.add_prefix("foo#", copy=False) - tm.assert_index_equal(ser_with_prefix.index, expected) - assert tm.shares_memory(ser_with_prefix, ser) - - with_suffix = float_frame.add_suffix("#foo", copy=True) - expected = Index([f"{c}#foo" for c in float_frame.columns]) - tm.assert_index_equal(with_suffix.columns, expected) - assert not any( - tm.shares_memory(float_frame.iloc[:, i], with_suffix.iloc[:, i]) - for i in range(float_frame.shape[1]) - ) - - ser_with_suffix = ser.add_suffix("#foo", copy=True) - tm.assert_index_equal(ser_with_suffix.index, expected) - assert not tm.shares_memory(ser_with_suffix, ser) - - with_suffix = float_frame.add_suffix("#foo", copy=False) - expected = Index([f"{c}#foo" for c in float_frame.columns]) - tm.assert_index_equal(with_suffix.columns, expected) - assert all( - tm.shares_memory(float_frame.iloc[:, i], with_suffix.iloc[:, i]) - for i in range(float_frame.shape[1]) - ) - - ser_with_suffix = ser.add_suffix("#foo", copy=False) - tm.assert_index_equal(ser_with_suffix.index, expected) - assert tm.shares_memory(ser_with_suffix, ser) - - def test_add_prefix_suffix_axis(float_frame): # GH 47819 with_prefix = float_frame.add_prefix("foo#", axis=0) @@ -90,4 +37,3 @@ def test_add_prefix_suffix_axis(float_frame): with_pct_suffix = float_frame.add_suffix("#foo", axis=1) expected = Index([f"{c}#foo" for c in float_frame.columns]) tm.assert_index_equal(with_pct_suffix.columns, expected) - From 420b83707d79d1de56641d9fff38efa0b3d5cb7b Mon Sep 17 00:00:00 2001 From: dannyi96 Date: Tue, 23 Aug 2022 15:53:35 +0530 Subject: [PATCH 11/15] address merge conflixts --- pandas/core/generic.py | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/pandas/core/generic.py b/pandas/core/generic.py index e53b81e9d31e0..38956e1faa57c 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -4619,9 +4619,7 @@ def _update_inplace(self, result, verify_is_copy: bool_t = True) -> None: self._maybe_update_cacher(verify_is_copy=verify_is_copy, inplace=True) @final - def add_prefix( - self: NDFrameT, prefix: str, axis: Axis | None = None - ) -> NDFrameT: + def add_prefix(self: NDFrameT, prefix: str, axis: Axis | None = None) -> NDFrameT: """ Prefix labels with string `prefix`. @@ -4693,9 +4691,7 @@ def add_prefix( return self._rename(**mapper) # type: ignore[return-value, arg-type] @final - def add_suffix( - self: NDFrameT, suffix: str, axis: Axis | None = None - ) -> NDFrameT: + def add_suffix(self: NDFrameT, suffix: str, axis: Axis | None = None) -> NDFrameT: """ Suffix labels with string `suffix`. From 10a1ea2019ad76b914902475be4ec2cca7f3ce15 Mon Sep 17 00:00:00 2001 From: dannyi96 Date: Fri, 26 Aug 2022 21:17:18 +0530 Subject: [PATCH 12/15] updated whatsnew --- doc/source/whatsnew/v1.5.0.rst | 1 - doc/source/whatsnew/v1.6.0.rst | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/doc/source/whatsnew/v1.5.0.rst b/doc/source/whatsnew/v1.5.0.rst index bf01f59186991..9de855dea407d 100644 --- a/doc/source/whatsnew/v1.5.0.rst +++ b/doc/source/whatsnew/v1.5.0.rst @@ -331,7 +331,6 @@ Other enhancements - Added ``copy`` keyword to :meth:`Series.set_axis` and :meth:`DataFrame.set_axis` to allow user to set axis on a new object without necessarily copying the underlying data (:issue:`47932`) - :meth:`DataFrame.set_index` now supports a ``copy`` keyword. If ``False``, the underlying data is not copied when a new :class:`DataFrame` is returned (:issue:`48043`) - The method :meth:`.ExtensionArray.factorize` accepts ``use_na_sentinel=False`` for determining how null values are to be treated (:issue:`46601`) -- :meth:`Series.add_suffix`, :meth:`DataFrame.add_suffix`, :meth:`Series.add_prefix` and :meth:`DataFrame.add_prefix` support an ``axis`` argument. If ``axis`` is set, the default behaviour of which axis to consider can be overwritten (:issue:`47819`) .. --------------------------------------------------------------------------- .. _whatsnew_150.notable_bug_fixes: diff --git a/doc/source/whatsnew/v1.6.0.rst b/doc/source/whatsnew/v1.6.0.rst index eac5e5d3a0f52..75f62824152e5 100644 --- a/doc/source/whatsnew/v1.6.0.rst +++ b/doc/source/whatsnew/v1.6.0.rst @@ -28,7 +28,7 @@ enhancement2 Other enhancements ^^^^^^^^^^^^^^^^^^ -- +- :meth:`Series.add_suffix`, :meth:`DataFrame.add_suffix`, :meth:`Series.add_prefix` and :meth:`DataFrame.add_prefix` support an ``axis`` argument. If ``axis`` is set, the default behaviour of which axis to consider can be overwritten (:issue:`47819`) - .. --------------------------------------------------------------------------- From e0244252afda16f1299db59677f00c5dd6c70818 Mon Sep 17 00:00:00 2001 From: dannyi96 Date: Sat, 27 Aug 2022 01:39:17 +0530 Subject: [PATCH 13/15] review comments --- .../frame/methods/test_add_prefix_suffix.py | 9 +++++ .../series/methods/test_add_prefix_suffix.py | 40 +++++++++++++++++++ 2 files changed, 49 insertions(+) create mode 100644 pandas/tests/series/methods/test_add_prefix_suffix.py diff --git a/pandas/tests/frame/methods/test_add_prefix_suffix.py b/pandas/tests/frame/methods/test_add_prefix_suffix.py index 725a8088fbfa0..1d9d2338279da 100644 --- a/pandas/tests/frame/methods/test_add_prefix_suffix.py +++ b/pandas/tests/frame/methods/test_add_prefix_suffix.py @@ -1,5 +1,6 @@ from pandas import Index import pandas._testing as tm +import pytest def test_add_prefix_suffix(float_frame): @@ -37,3 +38,11 @@ def test_add_prefix_suffix_axis(float_frame): with_pct_suffix = float_frame.add_suffix("#foo", axis=1) expected = Index([f"{c}#foo" for c in float_frame.columns]) tm.assert_index_equal(with_pct_suffix.columns, expected) + + +def test_add_prefix_suffix_invalid_axis(float_frame): + with pytest.raises(ValueError, match="No axis named 2 for object type DataFrame"): + float_frame.add_prefix("foo#", axis=2) + + with pytest.raises(ValueError, match="No axis named 2 for object type DataFrame"): + float_frame.add_suffix("foo#", axis=2) diff --git a/pandas/tests/series/methods/test_add_prefix_suffix.py b/pandas/tests/series/methods/test_add_prefix_suffix.py new file mode 100644 index 0000000000000..d2e9f89bfa968 --- /dev/null +++ b/pandas/tests/series/methods/test_add_prefix_suffix.py @@ -0,0 +1,40 @@ +from pandas import Index +import pandas._testing as tm +import pytest + + +def test_add_prefix_suffix(string_series): + with_prefix = string_series.add_prefix("foo#") + expected = Index([f"foo#{c}" for c in string_series.index]) + tm.assert_index_equal(with_prefix.index, expected) + + with_suffix = string_series.add_suffix("#foo") + expected = Index([f"{c}#foo" for c in string_series.index]) + tm.assert_index_equal(with_suffix.index, expected) + + with_pct_prefix = string_series.add_prefix("%") + expected = Index([f"%{c}" for c in string_series.index]) + tm.assert_index_equal(with_pct_prefix.index, expected) + + with_pct_suffix = string_series.add_suffix("%") + expected = Index([f"{c}%" for c in string_series.index]) + tm.assert_index_equal(with_pct_suffix.index, expected) + + +def test_add_prefix_suffix_axis(string_series): + # GH 47819 + with_prefix = string_series.add_prefix("foo#", axis=0) + expected = Index([f"foo#{c}" for c in string_series.index]) + tm.assert_index_equal(with_prefix.index, expected) + + with_pct_suffix = string_series.add_suffix("#foo", axis=0) + expected = Index([f"{c}#foo" for c in string_series.index]) + tm.assert_index_equal(with_pct_suffix.index, expected) + + +def test_add_prefix_suffix_invalid_axis(string_series): + with pytest.raises(ValueError, match="No axis named 1 for object type Series"): + string_series.add_prefix("foo#", axis=1) + + with pytest.raises(ValueError, match="No axis named 1 for object type Series"): + string_series.add_suffix("foo#", axis=1) From 2a8e3919478f2416c4d5a29fbecbfea3d93a5e48 Mon Sep 17 00:00:00 2001 From: dannyi96 Date: Sat, 27 Aug 2022 01:49:33 +0530 Subject: [PATCH 14/15] review comments --- pandas/tests/frame/methods/test_add_prefix_suffix.py | 3 ++- pandas/tests/series/methods/test_add_prefix_suffix.py | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/pandas/tests/frame/methods/test_add_prefix_suffix.py b/pandas/tests/frame/methods/test_add_prefix_suffix.py index 1d9d2338279da..92d7cdd7990e1 100644 --- a/pandas/tests/frame/methods/test_add_prefix_suffix.py +++ b/pandas/tests/frame/methods/test_add_prefix_suffix.py @@ -1,6 +1,7 @@ +import pytest + from pandas import Index import pandas._testing as tm -import pytest def test_add_prefix_suffix(float_frame): diff --git a/pandas/tests/series/methods/test_add_prefix_suffix.py b/pandas/tests/series/methods/test_add_prefix_suffix.py index d2e9f89bfa968..289a56b98b7e1 100644 --- a/pandas/tests/series/methods/test_add_prefix_suffix.py +++ b/pandas/tests/series/methods/test_add_prefix_suffix.py @@ -1,6 +1,7 @@ +import pytest + from pandas import Index import pandas._testing as tm -import pytest def test_add_prefix_suffix(string_series): From a97b1f093fb0b1cc5fa1126f614b498e1380fa0c Mon Sep 17 00:00:00 2001 From: dannyi96 Date: Wed, 31 Aug 2022 03:57:44 +0530 Subject: [PATCH 15/15] review comments --- pandas/core/generic.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pandas/core/generic.py b/pandas/core/generic.py index 97e3672e9c58d..f91d15e1a6487 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -4633,7 +4633,7 @@ def add_prefix(self: NDFrameT, prefix: str, axis: Axis | None = None) -> NDFrame axis : {{0 or 'index', 1 or 'columns', None}}, default None Axis to add prefix on - .. versionadded:: 1.5.0 + .. versionadded:: 1.6.0 Returns ------- @@ -4705,7 +4705,7 @@ def add_suffix(self: NDFrameT, suffix: str, axis: Axis | None = None) -> NDFrame axis : {{0 or 'index', 1 or 'columns', None}}, default None Axis to add suffix on - .. versionadded:: 1.5.0 + .. versionadded:: 1.6.0 Returns -------