Skip to content

Commit

Permalink
BUG: setting sparse panel fields should update member DataFrames
Browse files Browse the repository at this point in the history
  • Loading branch information
wesm committed Dec 5, 2011
1 parent 768af08 commit bc10c86
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 13 deletions.
50 changes: 38 additions & 12 deletions pandas/core/sparse.py
Original file line number Diff line number Diff line change
Expand Up @@ -1362,10 +1362,11 @@ def homogenize(series_dict):

return output

class PanelAxis(object):
class SparsePanelAxis(object):

def __init__(self, cache_field):
def __init__(self, cache_field, frame_attr):
self.cache_field = cache_field
self.frame_attr = frame_attr

def __get__(self, obj, type=None):
return getattr(obj, self.cache_field, None)
Expand All @@ -1376,6 +1377,9 @@ def __set__(self, obj, value):
if isinstance(value, MultiIndex):
raise NotImplementedError

for v in obj._frames.itervalues():
setattr(v, self.frame_attr, value)

setattr(obj, self.cache_field, value)

class SparsePanel(Panel):
Expand All @@ -1398,10 +1402,6 @@ class SparsePanel(Panel):
Notes
-----
"""
items = PanelAxis('_items')
major_axis = PanelAxis('_major_axis')
minor_axis = PanelAxis('_minor_axis')

ndim = 3

def __init__(self, frames, items=None, major_axis=None, minor_axis=None,
Expand Down Expand Up @@ -1429,7 +1429,7 @@ def __init__(self, frames, items=None, major_axis=None, minor_axis=None,
if item not in clean_frames:
raise Exception('column %s not found in data' % item)

self.items = items
self._items = items
self.major_axis = major_axis
self.minor_axis = minor_axis

Expand Down Expand Up @@ -1461,6 +1461,32 @@ def values(self):
return np.array([self._frames[item].values
for item in self.items])

# need a special property for items to make the field assignable

_items = None
def _get_items(self):
return self._items

def _set_items(self, new_items):
new_items = _ensure_index(new_items)
if isinstance(new_items, MultiIndex):
raise NotImplementedError

# need to create new frames dict

old_frame_dict = self._frames
old_items = self._items
self._frames = dict((new_k, old_frame_dict[old_k])
for new_k, old_k in zip(new_items, old_items))
self._items = new_items
items = property(fget=_get_items, fset=_set_items)

# DataFrame's index
major_axis = SparsePanelAxis('_major_axis', 'index')

# DataFrame's columns / "items"
minor_axis = SparsePanelAxis('_minor_axis', 'columns')

def __getitem__(self, key):
"""
"""
Expand All @@ -1479,13 +1505,13 @@ def __setitem__(self, key, value):
self._frames[key] = value

if key not in self.items:
self.items = Index(list(self.items) + [key])
self._items = Index(list(self.items) + [key])

def __delitem__(self, key):
loc = self.items.get_loc(key)
indices = range(loc) + range(loc + 1, len(self.items))
self.items = self.items[indices]
del self._frames[key]
self._items = self._items.take(indices)

def __getstate__(self):
# pickling
Expand All @@ -1498,9 +1524,9 @@ def __setstate__(self, state):

self.default_fill_value = fv
self.default_kind = kind
self.items = _unpickle_array(items)
self.major_axis = _unpickle_array(major)
self.minor_axis = _unpickle_array(minor)
self._items = _unpickle_array(items)
self._major_axis = _unpickle_array(major)
self._minor_axis = _unpickle_array(minor)
self._frames = frames

def copy(self):
Expand Down
4 changes: 3 additions & 1 deletion pandas/tests/test_panel.py
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,9 @@ def test_set_axis(self):
# ensure propagate to potentially prior-cached items too
item = self.panel['ItemA']
self.panel.items = new_items
self.assert_(self.panel[0] is not item)

if hasattr(self.panel, '_item_cache'):
self.assert_('ItemA' not in self.panel._item_cache)
self.assert_(self.panel.items is new_items)

item = self.panel[0]
Expand Down

0 comments on commit bc10c86

Please sign in to comment.