Skip to content

Commit 0f9647e

Browse files
Avoid reindexing values assigned to a multi-index when cols_droplevel contains empty values (#62404)
1 parent 64610ec commit 0f9647e

File tree

3 files changed

+28
-0
lines changed

3 files changed

+28
-0
lines changed

doc/source/whatsnew/v3.0.0.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -999,6 +999,7 @@ MultiIndex
999999
- Bug in :class:`DataFrame` arithmetic operations in case of unaligned MultiIndex columns (:issue:`60498`)
10001000
- Bug in :class:`DataFrame` arithmetic operations with :class:`Series` in case of unaligned MultiIndex (:issue:`61009`)
10011001
- Bug in :meth:`MultiIndex.from_tuples` causing wrong output with input of type tuples having NaN values (:issue:`60695`, :issue:`60988`)
1002+
- Bug in :meth:`DataFrame.__setitem__` where column alignment logic would reindex the assigned value with an empty index, incorrectly setting all values to ``NaN``.(:issue:`61841`)
10021003
- Bug in :meth:`DataFrame.reindex` and :meth:`Series.reindex` where reindexing :class:`Index` to a :class:`MultiIndex` would incorrectly set all values to ``NaN``.(:issue:`60923`)
10031004

10041005
I/O

pandas/core/frame.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4452,6 +4452,11 @@ def _set_item_frame_value(self, key, value: DataFrame) -> None:
44524452
loc, (slice, Series, np.ndarray, Index)
44534453
):
44544454
cols_droplevel = maybe_droplevels(cols, key)
4455+
if (
4456+
not isinstance(cols_droplevel, MultiIndex)
4457+
and not cols_droplevel.any()
4458+
):
4459+
return
44554460
if len(cols_droplevel) and not cols_droplevel.equals(value.columns):
44564461
value = value.reindex(cols_droplevel, axis=1)
44574462

pandas/tests/indexing/multiindex/test_multiindex.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,3 +249,25 @@ def test_groupyby_rename_categories_operation_with_multiindex(self, operation):
249249
expected = getattr(a, operation)(b.sort_index(ascending=False))
250250

251251
tm.assert_series_equal(result, expected)
252+
253+
def test_multiindex_assign_aligns_as_implicit_tuple(self):
254+
# GH 61841
255+
cols = MultiIndex.from_tuples([("A", "B")])
256+
df1 = DataFrame([[i] for i in range(3)], columns=cols)
257+
df2 = df1.copy()
258+
df3 = df1.copy()
259+
s1 = df1["A"].rolling(2).mean()
260+
s2 = s1.copy()
261+
s3 = s1.copy()
262+
263+
df2["C"] = s2
264+
df3[("C", "")] = s3
265+
tm.assert_frame_equal(df2, df3)
266+
267+
df1["C"] = s1
268+
tm.assert_frame_equal(df1, df2)
269+
tm.assert_frame_equal(df1, df3)
270+
271+
df1["C"] = s1
272+
tm.assert_frame_equal(df1, df2)
273+
tm.assert_frame_equal(df1, df3)

0 commit comments

Comments
 (0)