Skip to content

Commit b2a0a24

Browse files
lukemanleymroeschke
authored andcommitted
REGR: setitem with part of a MultiIndex raises (pandas-dev#54885)
1 parent a53f896 commit b2a0a24

File tree

3 files changed

+22
-4
lines changed

3 files changed

+22
-4
lines changed

doc/source/whatsnew/v2.1.1.rst

+1-1
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

+3-3
Original file line numberDiff line numberDiff line change
@@ -2454,12 +2454,12 @@ def _reorder_ilevels(self, order) -> MultiIndex:
24542454
def _recode_for_new_levels(
24552455
self, new_levels, copy: bool = True
24562456
) -> Generator[np.ndarray, None, None]:
2457-
if len(new_levels) != self.nlevels:
2457+
if len(new_levels) > self.nlevels:
24582458
raise AssertionError(
24592459
f"Length of new_levels ({len(new_levels)}) "
2460-
f"must be same as self.nlevels ({self.nlevels})"
2460+
f"must be <= self.nlevels ({self.nlevels})"
24612461
)
2462-
for i in range(self.nlevels):
2462+
for i in range(len(new_levels)):
24632463
yield recode_for_categories(
24642464
self.codes[i], self.levels[i], new_levels[i], copy=copy
24652465
)

pandas/tests/indexing/multiindex/test_setitem.py

+18
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)