Skip to content

Commit

Permalink
BUG: hack to enable zero-length data to be stored in HDFStore, close #…
Browse files Browse the repository at this point in the history
  • Loading branch information
wesm committed Aug 12, 2012
1 parent 65dde70 commit 603e5ae
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 16 deletions.
1 change: 1 addition & 0 deletions RELEASE.rst
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ pandas 0.8.2
caused by SeriesBinGrouper (#1648, #1688)
- When grouping by level, exclude unobserved levels (#1697)
- Don't lose tzinfo in DatetimeIndex when shifting by different offset (#1683)
- Hack to support storing data with a zero-length axis in HDFStore (#1707)

pandas 0.8.1
============
Expand Down
35 changes: 23 additions & 12 deletions pandas/io/pytables.py
Original file line number Diff line number Diff line change
Expand Up @@ -556,10 +556,6 @@ def _read_wide_table(self, group, where=None):

def _write_index(self, group, key, index):
if isinstance(index, MultiIndex):
if len(index) == 0:
raise ValueError('Can not write empty structure, '
'axis length was 0')

setattr(group._v_attrs, '%s_variety' % key, 'multi')
self._write_multi_index(group, key, index)
elif isinstance(index, BlockIndex):
Expand All @@ -569,10 +565,6 @@ def _write_index(self, group, key, index):
setattr(group._v_attrs, '%s_variety' % key, 'sparseint')
self._write_sparse_intindex(group, key, index)
else:
if len(index) == 0:
raise ValueError('Can not write empty structure, '
'axis length was 0')

setattr(group._v_attrs, '%s_variety' % key, 'regular')
converted, kind, _ = _convert_index(index)
self._write_array(group, key, converted)
Expand Down Expand Up @@ -658,7 +650,7 @@ def _read_multi_index(self, group, key):
names.append(name)

label_key = '%s_label%d' % (key, i)
lab = getattr(group, label_key)[:]
lab = _read_array(group, label_key)
labels.append(lab)

return MultiIndex(levels=levels, labels=labels, names=names)
Expand Down Expand Up @@ -719,7 +711,14 @@ def _write_array(self, group, key, value):
self.handle.createArray(group, key, value.view('i8'))
getattr(group, key)._v_attrs.value_type = 'datetime64'
else:
self.handle.createArray(group, key, value)
if any(x == 0 for x in value.shape):
# ugly hack for length 0 axes
arr = np.empty((1,) * value.ndim)
self.handle.createArray(group, key, arr)
getattr(group, key)._v_attrs.value_type = str(value.dtype)
getattr(group, key)._v_attrs.shape = value.shape
else:
self.handle.createArray(group, key, value)

def _write_table(self, group, items=None, index=None, columns=None,
values=None, append=False, compression=None):
Expand Down Expand Up @@ -805,7 +804,11 @@ def _read_group(self, group, where=None):

def _read_series(self, group, where=None):
index = self._read_index(group, 'index')
values = _read_array(group, 'values')
if len(index) > 0:
values = _read_array(group, 'values')
else:
values = []

name = getattr(group._v_attrs, 'name', None)
return Series(values, index=index, name=name)

Expand Down Expand Up @@ -959,7 +962,15 @@ def _read_array(group, key):
if isinstance(node, tables.VLArray):
return data[0]
else:
dtype = getattr(node._v_attrs, 'value_type', None)
attrs = node._v_attrs

dtype = getattr(attrs, 'value_type', None)
shape = getattr(attrs, 'shape', None)

if shape is not None:
# length 0 axis
return np.empty(shape, dtype=dtype)

if dtype == 'datetime64':
return np.array(data, dtype='M8[ns]')
return data
Expand Down
19 changes: 15 additions & 4 deletions pandas/io/tests/test_pytables.py
Original file line number Diff line number Diff line change
Expand Up @@ -338,8 +338,20 @@ def test_frame(self):
self.assert_(recons._data.is_consolidated())

# empty
self.assertRaises(ValueError, self._check_roundtrip, df[:0],
tm.assert_frame_equal)
self._check_roundtrip(df[:0], tm.assert_frame_equal)

def test_empty_series_frame(self):
s0 = Series()
s1 = Series(name='myseries')
df0 = DataFrame()
df1 = DataFrame(index=['a', 'b', 'c'])
df2 = DataFrame(columns=['d', 'e', 'f'])

self._check_roundtrip(s0, tm.assert_series_equal)
self._check_roundtrip(s1, tm.assert_series_equal)
self._check_roundtrip(df0, tm.assert_frame_equal)
self._check_roundtrip(df1, tm.assert_frame_equal)
self._check_roundtrip(df2, tm.assert_frame_equal)

def test_can_serialize_dates(self):
rng = [x.date() for x in bdate_range('1/1/2000', '1/30/2000')]
Expand Down Expand Up @@ -477,8 +489,7 @@ def _check(left, right):
self._check_roundtrip(wp.to_frame(), _check)

# empty
self.assertRaises(ValueError, self._check_roundtrip, wp.to_frame()[:0],
_check)
# self._check_roundtrip(wp.to_frame()[:0], _check)

def test_longpanel(self):
pass
Expand Down

0 comments on commit 603e5ae

Please sign in to comment.