Skip to content

Commit 9f7dbdd

Browse files
committed
BUG: Fixed a bug in DataFrame/Panel cache insertion and subsequent indexing GH4939
1 parent 0eab187 commit 9f7dbdd

File tree

4 files changed

+30
-4
lines changed

4 files changed

+30
-4
lines changed

doc/source/release.rst

+1
Original file line numberDiff line numberDiff line change
@@ -438,6 +438,7 @@ Bug Fixes
438438
- Fixed a bug in ``Series.hist`` where two figures were being created when
439439
the ``by`` argument was passed (:issue:`4112`, :issue:`4113`).
440440
- Fixed a bug in ``convert_objects`` for > 2 ndims (:issue:`4937`)
441+
- Fixed a bug in DataFrame/Panel cache insertion and subsequent indexing (:issue:`4939`)
441442

442443
pandas 0.12.0
443444
-------------

pandas/core/generic.py

+10-4
Original file line numberDiff line numberDiff line change
@@ -825,14 +825,20 @@ def _maybe_cache_changed(self, item, value):
825825
maybe it has changed """
826826
self._data.set(item, value)
827827

828-
def _maybe_update_cacher(self):
829-
""" see if we need to update our parent cacher """
828+
def _maybe_update_cacher(self, clear=False):
829+
""" see if we need to update our parent cacher
830+
if clear, then clear our cache """
830831
cacher = getattr(self,'_cacher',None)
831832
if cacher is not None:
832833
cacher[1]()._maybe_cache_changed(cacher[0],self)
834+
if clear:
835+
self._clear_item_cache()
833836

834-
def _clear_item_cache(self):
835-
self._item_cache.clear()
837+
def _clear_item_cache(self, i=None):
838+
if i is not None:
839+
self._item_cache.pop(i,None)
840+
else:
841+
self._item_cache.clear()
836842

837843
def _set_item(self, key, value):
838844
self._data.set(key, value)

pandas/core/indexing.py

+4
Original file line numberDiff line numberDiff line change
@@ -190,12 +190,14 @@ def _setitem_with_indexer(self, indexer, value):
190190

191191
new_values = np.concatenate([self.obj.values, [value]])
192192
self.obj._data = self.obj._constructor(new_values, index=new_index, name=self.obj.name)
193+
self.obj._maybe_update_cacher(clear=True)
193194
return self.obj
194195

195196
elif self.ndim == 2:
196197
index = self.obj._get_axis(0)
197198
labels = _safe_append_to_index(index, indexer)
198199
self.obj._data = self.obj.reindex_axis(labels,0)._data
200+
self.obj._maybe_update_cacher(clear=True)
199201
return getattr(self.obj,self.name).__setitem__(indexer,value)
200202

201203
# set using setitem (Panel and > dims)
@@ -255,6 +257,7 @@ def setter(item, v):
255257
# set the item, possibly having a dtype change
256258
s = s.copy()
257259
s._data = s._data.setitem(pi,v)
260+
s._maybe_update_cacher(clear=True)
258261
self.obj[item] = s
259262

260263
def can_do_equal_len():
@@ -327,6 +330,7 @@ def can_do_equal_len():
327330
value = self._align_panel(indexer, value)
328331

329332
self.obj._data = self.obj._data.setitem(indexer,value)
333+
self.obj._maybe_update_cacher(clear=True)
330334

331335
def _align_series(self, indexer, ser):
332336
# indexer to assign Series can be tuple or scalar

pandas/tests/test_indexing.py

+15
Original file line numberDiff line numberDiff line change
@@ -1480,6 +1480,21 @@ def test_series_partial_set(self):
14801480
result = ser.iloc[[1,1,0,0]]
14811481
assert_series_equal(result, expected)
14821482

1483+
def test_cache_updating(self):
1484+
# GH 4939, make sure to update the cache on setitem
1485+
1486+
df = tm.makeDataFrame()
1487+
df['A'] # cache series
1488+
df.ix["Hello Friend"] = df.ix[0]
1489+
self.assert_("Hello Friend" in df['A'].index)
1490+
self.assert_("Hello Friend" in df['B'].index)
1491+
1492+
panel = tm.makePanel()
1493+
panel.ix[0] # get first item into cache
1494+
panel.ix[:, :, 'A+1'] = panel.ix[:, :, 'A'] + 1
1495+
self.assert_("A+1" in panel.ix[0].columns)
1496+
self.assert_("A+1" in panel.ix[1].columns)
1497+
14831498
if __name__ == '__main__':
14841499
import nose
14851500
nose.runmodule(argv=[__file__, '-vvs', '-x', '--pdb', '--pdb-failure'],

0 commit comments

Comments
 (0)