From 74fee3d666035e5828e71f6d008122a6c8a530f2 Mon Sep 17 00:00:00 2001 From: jreback Date: Fri, 17 May 2013 07:59:30 -0400 Subject: [PATCH 1/2] BUG: (GH3626) issue with alignment of a DataFrame setitem with a piece of another DataFrame --- RELEASE.rst | 2 ++ pandas/core/indexing.py | 2 +- pandas/tests/test_indexing.py | 25 +++++++++++++++++++++++++ 3 files changed, 28 insertions(+), 1 deletion(-) diff --git a/RELEASE.rst b/RELEASE.rst index 219eec42ec20f..19073c97d92eb 100644 --- a/RELEASE.rst +++ b/RELEASE.rst @@ -125,6 +125,7 @@ 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_) .. _GH3164: https://github.com/pydata/pandas/issues/3164 .. _GH2786: https://github.com/pydata/pandas/issues/2786 @@ -177,6 +178,7 @@ pandas 0.11.1 .. _GH3611: https://github.com/pydata/pandas/issues/3611 .. _GH3062: https://github.com/pydata/pandas/issues/3062 .. _GH3624: https://github.com/pydata/pandas/issues/3624 +.. _GH3626: https://github.com/pydata/pandas/issues/3626 .. _GH1512: https://github.com/pydata/pandas/issues/1512 diff --git a/pandas/core/indexing.py b/pandas/core/indexing.py index dd27fa5c3473c..a53afad36fb8e 100644 --- a/pandas/core/indexing.py +++ b/pandas/core/indexing.py @@ -138,7 +138,7 @@ def setter(item, v): # align to if item in value: v = value[item] - v = v.reindex(self.obj[item].reindex(v.index).dropna().index) + v = v.reindex(self.obj[item].index & v.index) setter(item, v.values) else: setter(item, np.nan) diff --git a/pandas/tests/test_indexing.py b/pandas/tests/test_indexing.py index 65e7516d4b082..c62a0037efceb 100644 --- a/pandas/tests/test_indexing.py +++ b/pandas/tests/test_indexing.py @@ -853,6 +853,31 @@ def test_iloc_panel_issue(self): self.assert_(p.iloc[1, :3, 1].shape == (3,)) self.assert_(p.iloc[:3, 1, 1].shape == (3,)) + def test_multi_assign(self): + + # GH 3626, an assignement of a sub-df to a df + df = DataFrame({'FC':['a','b','a','b','a','b'], + 'PF':[0,0,0,0,1,1], + 'col1':range(6), + 'col2':range(6,12)}) + df.ix[1,0]=np.nan + df2 = df.copy() + + mask=~df2.FC.isnull() + cols=['col1', 'col2'] + + dft = df2 * 2 + dft.ix[3,3] = np.nan + + 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'), + 'col2':[12,7,16,np.nan,20,22]}) + + df2.ix[mask, cols]= dft.ix[mask, cols] + assert_frame_equal(df2,expected) + df2.ix[mask, cols]= dft.ix[mask, cols] + assert_frame_equal(df2,expected) if __name__ == '__main__': import nose From eff90322117fe6194122490d0d75bb391b3afdb9 Mon Sep 17 00:00:00 2001 From: jreback Date: Fri, 17 May 2013 10:13:56 -0400 Subject: [PATCH 2/2] BUG: validate ndarray size correctly with assigning pieces to a DataFrame --- pandas/core/indexing.py | 4 ++-- pandas/tests/test_indexing.py | 10 ++++++++++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/pandas/core/indexing.py b/pandas/core/indexing.py index a53afad36fb8e..1cbc5abdc3ea3 100644 --- a/pandas/core/indexing.py +++ b/pandas/core/indexing.py @@ -144,8 +144,8 @@ def setter(item, v): setter(item, np.nan) # we have an equal len ndarray - elif isinstance(value, np.ndarray) and value.ndim > 1: - if len(labels) != len(value): + 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' ' setting with an ndarray') diff --git a/pandas/tests/test_indexing.py b/pandas/tests/test_indexing.py index c62a0037efceb..f6d106f422911 100644 --- a/pandas/tests/test_indexing.py +++ b/pandas/tests/test_indexing.py @@ -874,11 +874,21 @@ def test_multi_assign(self): 'col1':Series([0,1,4,6,8,10],dtype='float64'), 'col2':[12,7,16,np.nan,20,22]}) + + # frame on rhs df2.ix[mask, cols]= dft.ix[mask, cols] assert_frame_equal(df2,expected) df2.ix[mask, cols]= dft.ix[mask, cols] assert_frame_equal(df2,expected) + # with an ndarray on rhs + df2 = df.copy() + df2.ix[mask, cols]= dft.ix[mask, cols].values + assert_frame_equal(df2,expected) + df2.ix[mask, cols]= dft.ix[mask, cols].values + assert_frame_equal(df2,expected) + + if __name__ == '__main__': import nose nose.runmodule(argv=[__file__, '-vvs', '-x', '--pdb', '--pdb-failure'],