From 60b2d050f82c6350bff30f559e46e4de27450f4c Mon Sep 17 00:00:00 2001 From: Patrick Hoefler Date: Thu, 29 Dec 2022 00:30:03 +0100 Subject: [PATCH] ENH: Add lazy copy to swaplevel --- pandas/core/frame.py | 2 +- pandas/core/series.py | 11 ++++++----- pandas/tests/copy_view/test_methods.py | 18 ++++++++++++++++++ 3 files changed, 25 insertions(+), 6 deletions(-) diff --git a/pandas/core/frame.py b/pandas/core/frame.py index e671f45216968..d916fdc5a0ee4 100644 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -7254,7 +7254,7 @@ def nsmallest(self, n: int, columns: IndexLabel, keep: str = "first") -> DataFra ), ) def swaplevel(self, i: Axis = -2, j: Axis = -1, axis: Axis = 0) -> DataFrame: - result = self.copy() + result = self.copy(deep=None) axis = self._get_axis_number(axis) diff --git a/pandas/core/series.py b/pandas/core/series.py index b69fb4c1b58aa..6280e38a367a2 100644 --- a/pandas/core/series.py +++ b/pandas/core/series.py @@ -4071,7 +4071,9 @@ def nsmallest(self, n: int = 5, keep: str = "first") -> Series: dtype: object""" ), ) - def swaplevel(self, i: Level = -2, j: Level = -1, copy: bool = True) -> Series: + def swaplevel( + self, i: Level = -2, j: Level = -1, copy: bool | None = None + ) -> Series: """ Swap levels i and j in a :class:`MultiIndex`. @@ -4091,10 +4093,9 @@ def swaplevel(self, i: Level = -2, j: Level = -1, copy: bool = True) -> Series: {examples} """ assert isinstance(self.index, MultiIndex) - new_index = self.index.swaplevel(i, j) - return self._constructor(self._values, index=new_index, copy=copy).__finalize__( - self, method="swaplevel" - ) + result = self.copy(deep=copy) + result.index = self.index.swaplevel(i, j) + return result def reorder_levels(self, order: Sequence[Level]) -> Series: """ diff --git a/pandas/tests/copy_view/test_methods.py b/pandas/tests/copy_view/test_methods.py index 878f1d8089d33..4a132becf99f4 100644 --- a/pandas/tests/copy_view/test_methods.py +++ b/pandas/tests/copy_view/test_methods.py @@ -424,6 +424,24 @@ def test_reorder_levels(using_copy_on_write): tm.assert_frame_equal(df, df_orig) +@pytest.mark.parametrize("obj", [Series([1, 2, 3]), DataFrame({"a": [1, 2, 3]})]) +def test_swaplevel(using_copy_on_write, obj): + index = MultiIndex.from_tuples([(1, 1), (1, 2), (2, 1)], names=["one", "two"]) + obj.index = index + obj_orig = obj.copy() + obj2 = obj.swaplevel() + + if using_copy_on_write: + assert np.shares_memory(obj2.values, obj.values) + else: + assert not np.shares_memory(obj2.values, obj.values) + + obj2.iloc[0] = 0 + if using_copy_on_write: + assert not np.shares_memory(obj2.values, obj.values) + tm.assert_equal(obj, obj_orig) + + def test_frame_set_axis(using_copy_on_write): # GH 49473 df = DataFrame({"a": [1, 2, 3], "b": [4, 5, 6], "c": [0.1, 0.2, 0.3]})