diff --git a/pandas/conftest.py b/pandas/conftest.py index be44e6c2b36da..d6b9576d7729f 100644 --- a/pandas/conftest.py +++ b/pandas/conftest.py @@ -1057,3 +1057,17 @@ def index_or_series_obj(request): copy to avoid mutation, e.g. setting .name """ return _index_or_series_objs[request.param].copy(deep=True) + + +@pytest.fixture +def multiindex_year_month_day_dataframe_random_data(): + """ + DataFrame with 3 level MultiIndex (year, month, day) covering + first 100 business days from 2000-01-01 with random data + """ + tdf = tm.makeTimeDataFrame(100) + ymd = tdf.groupby([lambda x: x.year, lambda x: x.month, lambda x: x.day]).sum() + # use Int64Index, to make sure things work + ymd.index.set_levels([lev.astype("i8") for lev in ymd.index.levels], inplace=True) + ymd.index.set_names(["year", "month", "day"], inplace=True) + return ymd diff --git a/pandas/tests/frame/test_alter_axes.py b/pandas/tests/frame/test_alter_axes.py index 34df8bb57dd91..e37170d4155f8 100644 --- a/pandas/tests/frame/test_alter_axes.py +++ b/pandas/tests/frame/test_alter_axes.py @@ -689,44 +689,6 @@ def test_rename_axis_mapper(self): with pytest.raises(TypeError, match="bogus"): df.rename_axis(bogus=None) - def test_reorder_levels(self): - index = MultiIndex( - levels=[["bar"], ["one", "two", "three"], [0, 1]], - codes=[[0, 0, 0, 0, 0, 0], [0, 1, 2, 0, 1, 2], [0, 1, 0, 1, 0, 1]], - names=["L0", "L1", "L2"], - ) - df = DataFrame({"A": np.arange(6), "B": np.arange(6)}, index=index) - - # no change, position - result = df.reorder_levels([0, 1, 2]) - tm.assert_frame_equal(df, result) - - # no change, labels - result = df.reorder_levels(["L0", "L1", "L2"]) - tm.assert_frame_equal(df, result) - - # rotate, position - result = df.reorder_levels([1, 2, 0]) - e_idx = MultiIndex( - levels=[["one", "two", "three"], [0, 1], ["bar"]], - codes=[[0, 1, 2, 0, 1, 2], [0, 1, 0, 1, 0, 1], [0, 0, 0, 0, 0, 0]], - names=["L1", "L2", "L0"], - ) - expected = DataFrame({"A": np.arange(6), "B": np.arange(6)}, index=e_idx) - tm.assert_frame_equal(result, expected) - - result = df.reorder_levels([0, 0, 0]) - e_idx = MultiIndex( - levels=[["bar"], ["bar"], ["bar"]], - codes=[[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]], - names=["L0", "L0", "L0"], - ) - expected = DataFrame({"A": np.arange(6), "B": np.arange(6)}, index=e_idx) - tm.assert_frame_equal(result, expected) - - result = df.reorder_levels(["L0", "L0", "L0"]) - tm.assert_frame_equal(result, expected) - def test_set_index_names(self): df = tm.makeDataFrame() df.index.name = "name" diff --git a/pandas/tests/generic/methods/test_reorder_levels.py b/pandas/tests/generic/methods/test_reorder_levels.py new file mode 100644 index 0000000000000..8bb6417e56659 --- /dev/null +++ b/pandas/tests/generic/methods/test_reorder_levels.py @@ -0,0 +1,73 @@ +import numpy as np +import pytest + +from pandas import DataFrame, MultiIndex, Series +import pandas._testing as tm + + +class TestReorderLevels: + @pytest.mark.parametrize("klass", [Series, DataFrame]) + def test_reorder_levels(self, klass): + index = MultiIndex( + levels=[["bar"], ["one", "two", "three"], [0, 1]], + codes=[[0, 0, 0, 0, 0, 0], [0, 1, 2, 0, 1, 2], [0, 1, 0, 1, 0, 1]], + names=["L0", "L1", "L2"], + ) + df = DataFrame({"A": np.arange(6), "B": np.arange(6)}, index=index) + obj = df if klass is DataFrame else df["A"] + + # no change, position + result = obj.reorder_levels([0, 1, 2]) + tm.assert_equal(obj, result) + + # no change, labels + result = obj.reorder_levels(["L0", "L1", "L2"]) + tm.assert_equal(obj, result) + + # rotate, position + result = obj.reorder_levels([1, 2, 0]) + e_idx = MultiIndex( + levels=[["one", "two", "three"], [0, 1], ["bar"]], + codes=[[0, 1, 2, 0, 1, 2], [0, 1, 0, 1, 0, 1], [0, 0, 0, 0, 0, 0]], + names=["L1", "L2", "L0"], + ) + expected = DataFrame({"A": np.arange(6), "B": np.arange(6)}, index=e_idx) + expected = expected if klass is DataFrame else expected["A"] + tm.assert_equal(result, expected) + + result = obj.reorder_levels([0, 0, 0]) + e_idx = MultiIndex( + levels=[["bar"], ["bar"], ["bar"]], + codes=[[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]], + names=["L0", "L0", "L0"], + ) + expected = DataFrame({"A": np.arange(6), "B": np.arange(6)}, index=e_idx) + expected = expected if klass is DataFrame else expected["A"] + tm.assert_equal(result, expected) + + result = obj.reorder_levels(["L0", "L0", "L0"]) + tm.assert_equal(result, expected) + + def test_reorder_levels_swaplevel_equivalence( + self, multiindex_year_month_day_dataframe_random_data + ): + + ymd = multiindex_year_month_day_dataframe_random_data + + result = ymd.reorder_levels(["month", "day", "year"]) + expected = ymd.swaplevel(0, 1).swaplevel(1, 2) + tm.assert_frame_equal(result, expected) + + result = ymd["A"].reorder_levels(["month", "day", "year"]) + expected = ymd["A"].swaplevel(0, 1).swaplevel(1, 2) + tm.assert_series_equal(result, expected) + + result = ymd.T.reorder_levels(["month", "day", "year"], axis=1) + expected = ymd.T.swaplevel(0, 1, axis=1).swaplevel(1, 2, axis=1) + tm.assert_frame_equal(result, expected) + + with pytest.raises(TypeError, match="hierarchical axis"): + ymd.reorder_levels([1, 2], axis=1) + + with pytest.raises(IndexError, match="Too many levels"): + ymd.index.reorder_levels([1, 2, 3]) diff --git a/pandas/tests/indexing/multiindex/conftest.py b/pandas/tests/indexing/multiindex/conftest.py index 0256f5e35e1db..c69d6f86a6ce6 100644 --- a/pandas/tests/indexing/multiindex/conftest.py +++ b/pandas/tests/indexing/multiindex/conftest.py @@ -2,7 +2,6 @@ import pytest from pandas import DataFrame, Index, MultiIndex -import pandas._testing as tm @pytest.fixture @@ -16,17 +15,3 @@ def multiindex_dataframe_random_data(): return DataFrame( np.random.randn(10, 3), index=index, columns=Index(["A", "B", "C"], name="exp") ) - - -@pytest.fixture -def multiindex_year_month_day_dataframe_random_data(): - """ - DataFrame with 3 level MultiIndex (year, month, day) covering - first 100 business days from 2000-01-01 with random data - """ - tdf = tm.makeTimeDataFrame(100) - ymd = tdf.groupby([lambda x: x.year, lambda x: x.month, lambda x: x.day]).sum() - # use Int64Index, to make sure things work - ymd.index.set_levels([lev.astype("i8") for lev in ymd.index.levels], inplace=True) - ymd.index.set_names(["year", "month", "day"], inplace=True) - return ymd diff --git a/pandas/tests/series/test_alter_axes.py b/pandas/tests/series/test_alter_axes.py index f6ca93b0c2882..769d1ed877a69 100644 --- a/pandas/tests/series/test_alter_axes.py +++ b/pandas/tests/series/test_alter_axes.py @@ -54,32 +54,6 @@ def test_set_index_makes_timeseries(self): s.index = idx assert s.index.is_all_dates - def test_reorder_levels(self): - index = MultiIndex( - levels=[["bar"], ["one", "two", "three"], [0, 1]], - codes=[[0, 0, 0, 0, 0, 0], [0, 1, 2, 0, 1, 2], [0, 1, 0, 1, 0, 1]], - names=["L0", "L1", "L2"], - ) - s = Series(np.arange(6), index=index) - - # no change, position - result = s.reorder_levels([0, 1, 2]) - tm.assert_series_equal(s, result) - - # no change, labels - result = s.reorder_levels(["L0", "L1", "L2"]) - tm.assert_series_equal(s, result) - - # rotate, position - result = s.reorder_levels([1, 2, 0]) - e_idx = MultiIndex( - levels=[["one", "two", "three"], [0, 1], ["bar"]], - codes=[[0, 1, 2, 0, 1, 2], [0, 1, 0, 1, 0, 1], [0, 0, 0, 0, 0, 0]], - names=["L1", "L2", "L0"], - ) - expected = Series(np.arange(6), index=e_idx) - tm.assert_series_equal(result, expected) - def test_rename_axis_mapper(self): # GH 19978 mi = MultiIndex.from_product([["a", "b", "c"], [1, 2]], names=["ll", "nn"]) diff --git a/pandas/tests/test_multilevel.py b/pandas/tests/test_multilevel.py index e3cf46b466ae4..84279d874bae1 100644 --- a/pandas/tests/test_multilevel.py +++ b/pandas/tests/test_multilevel.py @@ -939,25 +939,6 @@ def test_swaplevel(self): with pytest.raises(TypeError, match=msg): DataFrame(range(3)).swaplevel() - def test_reorder_levels(self): - result = self.ymd.reorder_levels(["month", "day", "year"]) - expected = self.ymd.swaplevel(0, 1).swaplevel(1, 2) - tm.assert_frame_equal(result, expected) - - result = self.ymd["A"].reorder_levels(["month", "day", "year"]) - expected = self.ymd["A"].swaplevel(0, 1).swaplevel(1, 2) - tm.assert_series_equal(result, expected) - - result = self.ymd.T.reorder_levels(["month", "day", "year"], axis=1) - expected = self.ymd.T.swaplevel(0, 1, axis=1).swaplevel(1, 2, axis=1) - tm.assert_frame_equal(result, expected) - - with pytest.raises(TypeError, match="hierarchical axis"): - self.ymd.reorder_levels([1, 2], axis=1) - - with pytest.raises(IndexError, match="Too many levels"): - self.ymd.index.reorder_levels([1, 2, 3]) - def test_insert_index(self): df = self.ymd[:5].T df[2000, 1, 10] = df[2000, 1, 7]