diff --git a/doc/source/v0.14.1.txt b/doc/source/v0.14.1.txt index 4959f52183a92..2e5d9b2140ae4 100644 --- a/doc/source/v0.14.1.txt +++ b/doc/source/v0.14.1.txt @@ -156,8 +156,7 @@ Bug Fixes ~~~~~~~~~ - - +- Bug Multiindex assignment with an aligned rhs (but at different levels) (:issue:`7475`) diff --git a/pandas/core/frame.py b/pandas/core/frame.py index 9c1d593187b2c..e7c064810a06d 100755 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -1980,6 +1980,19 @@ def _set_item(self, key, value): is_existing = key in self.columns self._ensure_valid_index(value) + + # have a new column, a multi-index, but no specification for the index, + # have to assume first level; this in effect broadcasts across the index + # GH 7475 + if not is_existing and isinstance(self.columns, MultiIndex) and not isinstance(key, tuple): + value_columns = self.columns.set_levels([[key]] + self.columns.levels[1:]) + value = self._sanitize_column(key, value) + if len(value_columns) != value.ndim: + raise ValueError("cannot assign to a multi-index with invalid dimensions") + for i, v in zip(value_columns,value): + NDFrame._set_item(self, i, v) + return self + value = self._sanitize_column(key, value) NDFrame._set_item(self, key, value) diff --git a/pandas/tests/test_indexing.py b/pandas/tests/test_indexing.py index c074c4333a774..0900ae8920ec8 100644 --- a/pandas/tests/test_indexing.py +++ b/pandas/tests/test_indexing.py @@ -1828,6 +1828,18 @@ def f(): df.loc['bar'] *= 2 self.assertRaises(TypeError, f) + def test_multiindex_setitem(self): + + # GH 7475 + # multi-index assignment + + df_orig = DataFrame(np.arange(10,dtype='int64').reshape(-1,2), columns=pd.MultiIndex.from_tuples([('Val','A'),('Val','B')])) + expected = concat([df_orig['Val'],df_orig['Val']/2],axis=1,keys=['Val','Half']) + + df = df_orig.copy() + df['Half'] = df['Val']/2 + assert_frame_equal(df,expected) + def test_getitem_multiindex(self): # GH 5725