Skip to content

BUG: Fix alignment issue when setitem in a mixed-DataFrame with a Series (GH3668) #3670

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 21, 2013
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion RELEASE.rst
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,8 @@ pandas 0.11.1
- Correctly parse date columns with embedded (nan/NaT) into datetime64[ns] dtype in ``read_csv``
when ``parse_dates`` is specified (GH3062_)
- Fix not consolidating before to_csv (GH3624_)
- Fix alignment issue when setitem in a DataFrame with a piece of a DataFrame (GH3626_)
- Fix alignment issue when setitem in a DataFrame with a piece of a DataFrame (GH3626_) or
a mixed DataFrame and a Series (GH3668_)
- Fix plotting of unordered DatetimeIndex (GH3601_)
- ``sql.write_frame`` failing when writing a single column to sqlite (GH3628_),
thanks to @stonebig
Expand Down Expand Up @@ -217,6 +218,7 @@ pandas 0.11.1
.. _GH3141: https://github.com/pydata/pandas/issues/3141
.. _GH3628: https://github.com/pydata/pandas/issues/3628
.. _GH3638: https://github.com/pydata/pandas/issues/3638
.. _GH3668: https://github.com/pydata/pandas/issues/3668
.. _GH3605: https://github.com/pydata/pandas/issues/3605
.. _GH3606: https://github.com/pydata/pandas/issues/3606
.. _GH3659: https://github.com/pydata/pandas/issues/3659
Expand Down
5 changes: 4 additions & 1 deletion pandas/core/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -851,6 +851,7 @@ def _maybe_upcast_indexer(result, indexer, other, dtype=None):
return the result and a changed flag
"""

original_dtype = result.dtype
def changeit():
# our type is wrong here, need to upcast
r, fill_value = _maybe_upcast(result, fill_value=other, dtype=dtype, copy=True)
Expand All @@ -861,9 +862,11 @@ def changeit():
# if we hit this then we still have an incompatible type
r[indexer] = fill_value

# if we have changed to floats, might want to cast back if we can
r = _possibly_downcast_to_dtype(r,original_dtype)
return r, True

new_dtype, fill_value = _maybe_promote(result.dtype,other)
new_dtype, fill_value = _maybe_promote(original_dtype,other)
if new_dtype != result.dtype:
return changeit()

Expand Down
5 changes: 3 additions & 2 deletions pandas/core/indexing.py
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ def setter(item, v):
else:
setter(item, np.nan)

# we have an equal len ndarray
# we have an equal len ndarray to our labels
elif isinstance(value, np.ndarray) and value.ndim == 2:
if len(labels) != value.shape[1]:
raise ValueError('Must have equal len keys and value when'
Expand All @@ -153,7 +153,8 @@ def setter(item, v):
setter(item, value[:,i])

# we have an equal len list/ndarray
elif len(labels) == 1 and len(self.obj[labels[0]]) == len(value):
elif len(labels) == 1 and (
len(self.obj[labels[0]]) == len(value) or len(plane_indexer[0]) == len(value)):
setter(labels[0], value)

# per label values
Expand Down
6 changes: 0 additions & 6 deletions pandas/tests/test_frame.py
Original file line number Diff line number Diff line change
Expand Up @@ -938,12 +938,6 @@ def test_getitem_setitem_non_ix_labels(self):
assert_frame_equal(result, expected)
assert_frame_equal(result2, expected)

def test_ix_assign_column_mixed(self):
# GH #1142
orig = self.mixed_frame.ix[:, 'B'].copy()
self.mixed_frame.ix[:, 'B'] = self.mixed_frame.ix[:, 'B'] + 1
assert_series_equal(self.mixed_frame.B, orig + 1)

def test_ix_multi_take(self):
df = DataFrame(np.random.randn(3, 2))
rs = df.ix[df.index == 0, :]
Expand Down
23 changes: 22 additions & 1 deletion pandas/tests/test_indexing.py
Original file line number Diff line number Diff line change
Expand Up @@ -881,7 +881,7 @@ def test_multi_assign(self):

expected = DataFrame({'FC':['a',np.nan,'a','b','a','b'],
'PF':[0,0,0,0,1,1],
'col1':Series([0,1,4,6,8,10],dtype='float64'),
'col1':Series([0,1,4,6,8,10]),
'col2':[12,7,16,np.nan,20,22]})


Expand All @@ -898,6 +898,27 @@ def test_multi_assign(self):
df2.ix[mask, cols]= dft.ix[mask, cols].values
assert_frame_equal(df2,expected)

def test_ix_assign_column_mixed(self):
# GH #1142
df = DataFrame(tm.getSeriesData())
df['foo'] = 'bar'

orig = df.ix[:, 'B'].copy()
df.ix[:, 'B'] = df.ix[:, 'B'] + 1
assert_series_equal(df.B, orig + 1)

# GH 3668, mixed frame with series value
df = DataFrame({'x':range(10), 'y':range(10,20),'z' : 'bar'})
expected = df.copy()
expected.ix[0, 'y'] = 1000
expected.ix[2, 'y'] = 1200
expected.ix[4, 'y'] = 1400
expected.ix[6, 'y'] = 1600
expected.ix[8, 'y'] = 1800

df.ix[df.x % 2 == 0, 'y'] = df.ix[df.x % 2 == 0, 'y'] * 100
assert_frame_equal(df,expected)

def test_iloc_mask(self):

# GH 3631, iloc with a mask (of a series) should raise
Expand Down