Skip to content

Commit 6884d1c

Browse files
authored
REGR: setitem with part of a MultiIndex raises (#54885)
1 parent b12fa3d commit 6884d1c

File tree

3 files changed

+22
-4
lines changed

3 files changed

+22
-4
lines changed

doc/source/whatsnew/v2.1.1.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ including other versions of pandas.
1313

1414
Fixed regressions
1515
~~~~~~~~~~~~~~~~~
16-
-
16+
- Fixed regression in :meth:`DataFrame.__setitem__` raising ``AssertionError`` when setting a :class:`Series` with a partial :class:`MultiIndex` (:issue:`54875`)
1717

1818
.. ---------------------------------------------------------------------------
1919
.. _whatsnew_211.bug_fixes:

pandas/core/indexes/multi.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2453,12 +2453,12 @@ def _reorder_ilevels(self, order) -> MultiIndex:
24532453
def _recode_for_new_levels(
24542454
self, new_levels, copy: bool = True
24552455
) -> Generator[np.ndarray, None, None]:
2456-
if len(new_levels) != self.nlevels:
2456+
if len(new_levels) > self.nlevels:
24572457
raise AssertionError(
24582458
f"Length of new_levels ({len(new_levels)}) "
2459-
f"must be same as self.nlevels ({self.nlevels})"
2459+
f"must be <= self.nlevels ({self.nlevels})"
24602460
)
2461-
for i in range(self.nlevels):
2461+
for i in range(len(new_levels)):
24622462
yield recode_for_categories(
24632463
self.codes[i], self.levels[i], new_levels[i], copy=copy
24642464
)

pandas/tests/indexing/multiindex/test_setitem.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -556,3 +556,21 @@ def test_frame_setitem_copy_no_write(
556556

557557
result = df
558558
tm.assert_frame_equal(result, expected)
559+
560+
561+
def test_frame_setitem_partial_multiindex():
562+
# GH 54875
563+
df = DataFrame(
564+
{
565+
"a": [1, 2, 3],
566+
"b": [3, 4, 5],
567+
"c": 6,
568+
"d": 7,
569+
}
570+
).set_index(["a", "b", "c"])
571+
ser = Series(8, index=df.index.droplevel("c"))
572+
result = df.copy()
573+
result["d"] = ser
574+
expected = df.copy()
575+
expected["d"] = 8
576+
tm.assert_frame_equal(result, expected)

0 commit comments

Comments
 (0)