Skip to content

Commit a015631

Browse files
authored
BUG: unstack accessing wrong index level when midx has mixed names (#49092)
* BUG: unstack accessing wrong index level when midx has mixed names * Add comment
1 parent 7a910de commit a015631

File tree

4 files changed

+30
-2
lines changed

4 files changed

+30
-2
lines changed

doc/source/whatsnew/v2.0.0.rst

+1
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,7 @@ Groupby/resample/rolling
265265
Reshaping
266266
^^^^^^^^^
267267
- Bug in :meth:`DataFrame.pivot_table` raising ``TypeError`` for nullable dtype and ``margins=True`` (:issue:`48681`)
268+
- Bug in :meth:`DataFrame.unstack` and :meth:`Series.unstack` unstacking wrong level of :class:`MultiIndex` when :class:`MultiIndex` has mixed names (:issue:`48763`)
268269
- Bug in :meth:`DataFrame.pivot` not respecting ``None`` as column name (:issue:`48293`)
269270
- Bug in :func:`join` when ``left_on`` or ``right_on`` is or includes a :class:`CategoricalIndex` incorrectly raising ``AttributeError`` (:issue:`48464`)
270271
-

pandas/core/reshape/reshape.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -470,9 +470,9 @@ def unstack(obj: Series | DataFrame, level, fill_value=None):
470470
else:
471471
level = level[0]
472472

473-
# Prioritize integer interpretation (GH #21677):
474473
if not is_integer(level) and not level == "__placeholder__":
475-
level = obj.index._get_level_number(level)
474+
# check if level is valid in case of regular index
475+
obj.index._get_level_number(level)
476476

477477
if isinstance(obj, DataFrame):
478478
if isinstance(obj.index, MultiIndex):

pandas/tests/frame/test_stack_unstack.py

+13
Original file line numberDiff line numberDiff line change
@@ -2183,3 +2183,16 @@ def test_stack_nullable_dtype(self):
21832183
# be an EA
21842184
expected = df.astype(object).stack("station")
21852185
tm.assert_frame_equal(result, expected)
2186+
2187+
def test_unstack_mixed_level_names(self):
2188+
# GH#48763
2189+
arrays = [["a", "a"], [1, 2], ["red", "blue"]]
2190+
idx = MultiIndex.from_arrays(arrays, names=("x", 0, "y"))
2191+
df = DataFrame({"m": [1, 2]}, index=idx)
2192+
result = df.unstack("x")
2193+
expected = DataFrame(
2194+
[[1], [2]],
2195+
columns=MultiIndex.from_tuples([("m", "a")], names=[None, "x"]),
2196+
index=MultiIndex.from_tuples([(1, "red"), (2, "blue")], names=[0, "y"]),
2197+
)
2198+
tm.assert_frame_equal(result, expected)

pandas/tests/series/methods/test_unstack.py

+14
Original file line numberDiff line numberDiff line change
@@ -147,3 +147,17 @@ def test_unstack_multi_index_categorical_values():
147147
index=dti.rename("major"),
148148
)
149149
tm.assert_frame_equal(result, expected)
150+
151+
152+
def test_unstack_mixed_level_names():
153+
# GH#48763
154+
arrays = [["a", "a"], [1, 2], ["red", "blue"]]
155+
idx = MultiIndex.from_arrays(arrays, names=("x", 0, "y"))
156+
ser = Series([1, 2], index=idx)
157+
result = ser.unstack("x")
158+
expected = DataFrame(
159+
[[1], [2]],
160+
columns=pd.Index(["a"], name="x"),
161+
index=MultiIndex.from_tuples([(1, "red"), (2, "blue")], names=[0, "y"]),
162+
)
163+
tm.assert_frame_equal(result, expected)

0 commit comments

Comments
 (0)