From 530477c8fd3824af76ae0a14f7b6b7326fc0e70a Mon Sep 17 00:00:00 2001 From: seljaks <33955366+seljaks@users.noreply.github.com> Date: Fri, 2 Dec 2022 17:46:38 +0100 Subject: [PATCH 1/3] TST: add test for reorder levels GH49473 --- pandas/tests/copy_view/test_methods.py | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/pandas/tests/copy_view/test_methods.py b/pandas/tests/copy_view/test_methods.py index bf65f153b10dd..a5fe52fce66d0 100644 --- a/pandas/tests/copy_view/test_methods.py +++ b/pandas/tests/copy_view/test_methods.py @@ -3,6 +3,7 @@ from pandas import ( DataFrame, + MultiIndex, Series, ) import pandas._testing as tm @@ -280,3 +281,22 @@ def test_head_tail(method, using_copy_on_write): # without CoW enabled, head and tail return views. Mutating df2 also mutates df. df2.iloc[0, 0] = 1 tm.assert_frame_equal(df, df_orig) + + +def test_reorder_levels(using_copy_on_write): + index = MultiIndex.from_tuples( + [(1, 1), (1, 2), (2, 1), (2, 2)], names=["one", "two"] + ) + df = DataFrame({"a": [1, 2, 3, 4]}, index=index) + df_orig = df.copy() + df2 = df.reorder_levels(order=["two", "one"]) + + if using_copy_on_write: + assert np.shares_memory(get_array(df2, "a"), get_array(df, "a")) + else: + assert not np.shares_memory(get_array(df2, "a"), get_array(df, "a")) + + df2.iloc[0, 0] = 0 + if using_copy_on_write: + assert not np.shares_memory(get_array(df2, "a"), get_array(df, "a")) + tm.assert_frame_equal(df, df_orig) From 7d2123d1ab145c2cbc108334d7335712d8c21569 Mon Sep 17 00:00:00 2001 From: seljaks <33955366+seljaks@users.noreply.github.com> Date: Fri, 2 Dec 2022 17:48:21 +0100 Subject: [PATCH 2/3] ENH: add copy on write for df reorder levels GH49473 --- pandas/core/frame.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/core/frame.py b/pandas/core/frame.py index 0144aefedaa5f..3d40b1c1a3c8d 100644 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -7452,7 +7452,7 @@ class diet if not isinstance(self._get_axis(axis), MultiIndex): # pragma: no cover raise TypeError("Can only reorder levels on a hierarchical axis.") - result = self.copy() + result = self.copy(deep=None) if axis == 0: assert isinstance(result.index, MultiIndex) From 1320934de7e99c2c6efa021a30b19efe1bd37f15 Mon Sep 17 00:00:00 2001 From: seljaks <33955366+seljaks@users.noreply.github.com> Date: Fri, 2 Dec 2022 17:51:07 +0100 Subject: [PATCH 3/3] TYP: change type hint to match method behavior GH49473 --- pandas/core/frame.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/core/frame.py b/pandas/core/frame.py index 3d40b1c1a3c8d..8c3e6d473b36e 100644 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -7407,7 +7407,7 @@ def swaplevel(self, i: Axis = -2, j: Axis = -1, axis: Axis = 0) -> DataFrame: result.columns = result.columns.swaplevel(i, j) return result - def reorder_levels(self, order: Sequence[Axis], axis: Axis = 0) -> DataFrame: + def reorder_levels(self, order: Sequence[int | str], axis: Axis = 0) -> DataFrame: """ Rearrange index levels using input order. May not drop or duplicate levels.