diff --git a/doc/source/release.rst b/doc/source/release.rst index 6e10bd651d90a..19639e2e759e1 100644 --- a/doc/source/release.rst +++ b/doc/source/release.rst @@ -660,7 +660,7 @@ Bug Fixes the ``by`` argument was passed (:issue:`4112`, :issue:`4113`). - Fixed a bug in ``convert_objects`` for > 2 ndims (:issue:`4937`) - Fixed a bug in DataFrame/Panel cache insertion and subsequent indexing - (:issue:`4939`) + (:issue:`4939`, :issue:`5424`) - Fixed string methods for ``FrozenNDArray`` and ``FrozenList`` (:issue:`4929`) - Fixed a bug with setting invalid or out-of-range values in indexing diff --git a/pandas/core/indexing.py b/pandas/core/indexing.py index 0bc0afaf255f2..c854e0b086994 100644 --- a/pandas/core/indexing.py +++ b/pandas/core/indexing.py @@ -189,9 +189,13 @@ def _setitem_with_indexer(self, indexer, value): return self.obj # reindex the axis + # make sure to clear the cache because we are + # just replacing the block manager here + # so the object is the same index = self.obj._get_axis(i) labels = _safe_append_to_index(index, key) self.obj._data = self.obj.reindex_axis(labels,i)._data + self.obj._maybe_update_cacher(clear=True) if isinstance(labels,MultiIndex): self.obj.sortlevel(inplace=True) @@ -223,7 +227,8 @@ def _setitem_with_indexer(self, indexer, value): if len(self.obj.values): new_values = np.concatenate([self.obj.values, new_values]) - self.obj._data = self.obj._constructor(new_values, index=new_index, name=self.obj.name) + self.obj._data = self.obj._constructor(new_values, + index=new_index, name=self.obj.name)._data self.obj._maybe_update_cacher(clear=True) return self.obj diff --git a/pandas/tests/test_frame.py b/pandas/tests/test_frame.py index b73c7cdbb8f87..6b487cb006a80 100644 --- a/pandas/tests/test_frame.py +++ b/pandas/tests/test_frame.py @@ -3539,24 +3539,6 @@ def test_operators_timedelta64(self): self.assertTrue(df['off1'].dtype == 'timedelta64[ns]') self.assertTrue(df['off2'].dtype == 'timedelta64[ns]') - def test__slice_consolidate_invalidate_item_cache(self): - # #3970 - df = DataFrame({ "aa":lrange(5), "bb":[2.2]*5}) - - # Creates a second float block - df["cc"] = 0.0 - - # caches a reference to the 'bb' series - df["bb"] - - # repr machinery triggers consolidation - repr(df) - - # Assignment to wrong series - df['bb'].iloc[0] = 0.17 - df._clear_item_cache() - self.assertAlmostEqual(df['bb'][0], 0.17) - def test_new_empty_index(self): df1 = DataFrame(randn(0, 3)) df2 = DataFrame(randn(0, 3)) diff --git a/pandas/tests/test_indexing.py b/pandas/tests/test_indexing.py index 2cb26804ea4be..2ad9f10d1b990 100644 --- a/pandas/tests/test_indexing.py +++ b/pandas/tests/test_indexing.py @@ -1645,6 +1645,41 @@ def test_cache_updating(self): result = df.loc[(0,0),'z'] self.assert_(result == 2) + def test_slice_consolidate_invalidate_item_cache(self): + # #3970 + df = DataFrame({ "aa":lrange(5), "bb":[2.2]*5}) + + # Creates a second float block + df["cc"] = 0.0 + + # caches a reference to the 'bb' series + df["bb"] + + # repr machinery triggers consolidation + repr(df) + + # Assignment to wrong series + df['bb'].iloc[0] = 0.17 + df._clear_item_cache() + self.assertAlmostEqual(df['bb'][0], 0.17) + + def test_setitem_cache_updating(self): + # GH 5424 + cont = ['one', 'two','three', 'four', 'five', 'six', 'seven'] + + for do_ref in [False,False]: + df = DataFrame({'a' : cont, "b":cont[3:]+cont[:3] ,'c' : np.arange(7)}) + + # ref the cache + if do_ref: + df.ix[0,"c"] + + # set it + df.ix[7,'c'] = 1 + + self.assert_(df.ix[0,'c'] == 0.0) + self.assert_(df.ix[7,'c'] == 1.0) + def test_floating_index_doc_example(self): index = Index([1.5, 2, 3, 4.5, 5])