Skip to content

Commit 6abbbc1

Browse files
committed
BUG: assigning multiple columns in a hierarchically indexed DataFrame. close #1803
1 parent fe0d641 commit 6abbbc1

File tree

6 files changed

+40
-6
lines changed

6 files changed

+40
-6
lines changed

LICENSES/NUMPY_LICENSE

Whitespace-only changes.

LICENSES/PSF_LICENSE

Whitespace-only changes.

LICENSES/SCIPY_LICENSE

Whitespace-only changes.

RELEASE.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,9 @@ pandas 0.10.0
108108
- Use `col_space` argument as minimum column width in DataFrame.to_html (#2328)
109109
- Fix tz-aware DatetimeIndex.to_period (#2232)
110110
- Fix DataFrame row indexing case with MultiIndex (#2314)
111+
- Fix to_excel exporting issues with Timestamp objects in index (#2294)
112+
- Fixes assigning scalars and array to hierarchical column chunk (#1803)
113+
111114

112115
pandas 0.9.1
113116
============

pandas/core/frame.py

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2092,14 +2092,30 @@ def _sanitize_column(self, key, value):
20922092
value = value.copy().T
20932093
else:
20942094
value = value.copy()
2095+
2096+
# Broadcasting funtimes
2097+
if key in self.columns and value.ndim == 1:
2098+
existing_piece = self[key]
2099+
if isinstance(existing_piece, DataFrame):
2100+
value = np.tile(value, (len(existing_piece.columns), 1))
20952101
else:
2096-
value = np.repeat(value, len(self.index))
20972102
if key in self.columns:
2098-
existing_column = self[key]
2099-
# special case for now
2100-
if (com.is_float_dtype(existing_column) and
2101-
com.is_integer_dtype(value)):
2102-
value = value.astype(np.float64)
2103+
existing_piece = self[key]
2104+
2105+
# transpose hack
2106+
if isinstance(existing_piece, DataFrame):
2107+
shape = (len(existing_piece.columns), len(self.index))
2108+
value = np.repeat(value, np.prod(shape)).reshape(shape)
2109+
else:
2110+
value = np.repeat(value, len(self.index))
2111+
2112+
# special case for now
2113+
if (com.is_float_dtype(existing_piece) and
2114+
com.is_integer_dtype(value)):
2115+
value = value.astype(np.float64)
2116+
2117+
else:
2118+
value = np.repeat(value, len(self.index))
21032119

21042120
return np.atleast_2d(np.asarray(value))
21052121

pandas/tests/test_multilevel.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,21 @@ def test_frame_setitem_multi_column(self):
291291
cp['a'] = cp['b'].values
292292
assert_frame_equal(cp['a'], cp['b'])
293293

294+
#----------------------------------------
295+
# #1803
296+
columns = MultiIndex.from_tuples([('A', '1'), ('A', '2'), ('B', '1')])
297+
df = DataFrame(index=[1, 3, 5], columns=columns)
298+
299+
# Works, but adds a column instead of updating the two existing ones
300+
df['A'] = 0.0 # Doesn't work
301+
self.assertTrue((df['A'].values == 0).all())
302+
303+
# it broadcasts
304+
df['B', '1'] = [1, 2, 3]
305+
df['A'] = df['B', '1']
306+
assert_almost_equal(df['A', '1'], df['B', '1'])
307+
assert_almost_equal(df['A', '2'], df['B', '1'])
308+
294309
def test_getitem_tuple_plus_slice(self):
295310
# GH #671
296311
df = DataFrame({'a' : range(10),

0 commit comments

Comments
 (0)