From 29edd119d31a9ee7d4f89e8c1dc8af96f0c19dce Mon Sep 17 00:00:00 2001 From: Tom Augspurger Date: Mon, 20 Jan 2020 16:25:32 -0600 Subject: [PATCH] BUG: Break reference from grouping level to MI (#31133) --- pandas/core/indexes/multi.py | 4 ++++ pandas/tests/groupby/test_apply.py | 17 +++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/pandas/core/indexes/multi.py b/pandas/core/indexes/multi.py index 8682af6ab6369..b684908c25fe5 100644 --- a/pandas/core/indexes/multi.py +++ b/pandas/core/indexes/multi.py @@ -1256,6 +1256,10 @@ def _get_grouper_for_level(self, mapper, level): if len(uniques) < len(level_index): # Remove unobserved levels from level_index level_index = level_index.take(uniques) + else: + # break references back to us so that setting the name + # on the output of a groupby doesn't reflect back here. + level_index = level_index.copy() if len(level_index): grouper = level_index.take(codes) diff --git a/pandas/tests/groupby/test_apply.py b/pandas/tests/groupby/test_apply.py index e81ff37510dc0..708d3429285a8 100644 --- a/pandas/tests/groupby/test_apply.py +++ b/pandas/tests/groupby/test_apply.py @@ -775,3 +775,20 @@ def most_common_values(df): ["17661101"], index=pd.DatetimeIndex(["2015-02-24"], name="day"), name="userId" ) tm.assert_series_equal(result, expected) + + +@pytest.mark.parametrize("category", [False, True]) +def test_apply_multi_level_name(category): + # https://github.com/pandas-dev/pandas/issues/31068 + b = [1, 2] * 5 + if category: + b = pd.Categorical(b, categories=[1, 2, 3]) + df = pd.DataFrame( + {"A": np.arange(10), "B": b, "C": list(range(10)), "D": list(range(10))} + ).set_index(["A", "B"]) + result = df.groupby("B").apply(lambda x: x.sum()) + expected = pd.DataFrame( + {"C": [20, 25], "D": [20, 25]}, index=pd.Index([1, 2], name="B") + ) + tm.assert_frame_equal(result, expected) + assert df.index.names == ["A", "B"]