From 3a2803ae2ba74b45010af1ada0e2c6d5decaee4a Mon Sep 17 00:00:00 2001 From: Patrick Hoefler Date: Sat, 15 Oct 2022 23:56:15 +0200 Subject: [PATCH] BUG: setitem raising for rhs with midx columns and tuple indexer --- doc/source/whatsnew/v2.0.0.rst | 1 + pandas/core/frame.py | 2 +- pandas/tests/frame/indexing/test_setitem.py | 8 ++++++++ 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/doc/source/whatsnew/v2.0.0.rst b/doc/source/whatsnew/v2.0.0.rst index 508d5d8bc4cc1..6511922fbf7b4 100644 --- a/doc/source/whatsnew/v2.0.0.rst +++ b/doc/source/whatsnew/v2.0.0.rst @@ -216,6 +216,7 @@ Interval Indexing ^^^^^^^^ - Bug in :meth:`DataFrame.reindex` filling with wrong values when indexing columns and index for ``uint`` dtypes (:issue:`48184`) +- Bug in :meth:`DataFrame.__setitem__` raising ``ValueError`` when right hand side is :class:`DataFrame` with :class:`MultiIndex` columns (:issue:`49121`) - Bug in :meth:`DataFrame.reindex` casting dtype to ``object`` when :class:`DataFrame` has single extension array column when re-indexing ``columns`` and ``index`` (:issue:`48190`) - Bug in :func:`~DataFrame.describe` when formatting percentiles in the resulting index showed more decimals than needed (:issue:`46362`) diff --git a/pandas/core/frame.py b/pandas/core/frame.py index 8b6235374bed0..e51f8d7757241 100644 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -4110,7 +4110,7 @@ def _set_item_frame_value(self, key, value: DataFrame) -> None: if key in self.columns: loc = self.columns.get_loc(key) cols = self.columns[loc] - len_cols = 1 if is_scalar(cols) else len(cols) + len_cols = 1 if is_scalar(cols) or isinstance(cols, tuple) else len(cols) if len_cols != len(value.columns): raise ValueError("Columns must be same length as key") diff --git a/pandas/tests/frame/indexing/test_setitem.py b/pandas/tests/frame/indexing/test_setitem.py index c30ffcf9a7e5b..2f103fe2496f1 100644 --- a/pandas/tests/frame/indexing/test_setitem.py +++ b/pandas/tests/frame/indexing/test_setitem.py @@ -748,6 +748,14 @@ def test_setitem_frame_overwrite_with_ea_dtype(self, any_numeric_ea_dtype): ) tm.assert_frame_equal(df, expected) + def test_setitem_frame_midx_columns(self): + # GH#49121 + df = DataFrame({("a", "b"): [10]}) + expected = df.copy() + col_name = ("a", "b") + df[col_name] = df[[col_name]] + tm.assert_frame_equal(df, expected) + class TestSetitemTZAwareValues: @pytest.fixture