使用pandas.HDFStore读取HDF5文件中的整个组
我有一个HDF文件,内容大致如下:
>>> dataset.store
... <class 'pandas.io.pytables.HDFStore'>
... File path: ../data/data_experiments_01-02-03.h5
... /exp01/user01 frame_table (typ->appendable,nrows->221,ncols->124,indexers->[index])
... /exp01/user02 frame_table (typ->appendable,nrows->163,ncols->124,indexers->[index])
... /exp01/user03 frame_table (typ->appendable,nrows->145,ncols->124,indexers->[index])
... /exp02/user01 frame_table (typ->appendable,nrows->194,ncols->124,indexers->[index])
... /exp02/user02 frame_table (typ->appendable,nrows->145,ncols->124,indexers->[index])
... /exp03/user03 frame_table (typ->appendable,nrows->348,ncols->124,indexers->[index])
... /exp03/user01 frame_table (typ->appendable,nrows->240,ncols->124,indexers->[index])
我想从其中一个实验(exp0Z)中提取所有用户(userXY),并把它们合并成一个大的数据框(DataFrame)。我尝试使用 store.get('exp03')
,结果出现了以下错误:
>>> store.get('exp03')
...
... ---------------------------------------------------------------------------
... TypeError Traceback (most recent call last)
... <ipython-input-109-0a2e29e9e0a4> in <module>()
... ----> 1 dataset.store.get('/exp03')
...
... /Library/Python/2.7/site-packages/pandas/io/pytables.pyc in get(self, key)
... 613 if group is None:
... 614 raise KeyError('No object named %s in the file' % key)
... --> 615 return self._read_group(group)
... 616
... 617 def select(self, key, where=None, start=None, stop=None, columns=None,
...
... /Library/Python/2.7/site-packages/pandas/io/pytables.pyc in _read_group(self, group, **kwargs)
... 1277
... 1278 def _read_group(self, group, **kwargs):
... -> 1279 s = self._create_storer(group)
... 1280 s.infer_axes()
... 1281 return s.read(**kwargs)
...
... /Library/Python/2.7/site-packages/pandas/io/pytables.pyc in _create_storer(self, group, format, value, append, **kwargs)
... 1160 else:
... 1161 raise TypeError(
... -> 1162 "cannot create a storer if the object is not existing "
... 1163 "nor a value are passed")
... 1164 else:
...
... TypeError: cannot create a storer if the object is not existing nor a value are passed
我可以通过调用 store.get('exp03/user01')
来获取单个用户的数据,所以我猜测可以通过 store.keys()
来遍历所有用户,然后手动把获取到的数据框合并起来。不过,我在想是否可以通过一次调用 store.get()
或其他类似的方法来实现这个操作。
补充说明:注意数据集是一个包含我的 pandas.HDFstore 的类。
1 个回答
5
这个功能还没有实现,不过如果能有的话会很不错。(顺便说一下,我不会在.get(...)
中默认设置这个功能,因为这样不够明确,比如说它是不是应该总是读取所有的表,这样会有太多的猜测。)不过可以有一个参数来控制读取哪些子表。如果你有兴趣实现这个功能,请把它放到GitHub上。
不过你可以使用一些内部函数,这样会简单很多(你甚至可以给每个选择传递一个where
条件)。
In [13]: store = pd.HDFStore('test.h5',mode='w')
In [14]: store.append('df/foo1',DataFrame(np.random.randn(10,2)))
In [15]: store.append('df/foo2',DataFrame(np.random.randn(10,2)))
In [16]: pd.concat([ store.select(node._v_pathname) for node in store.get_node('df') ])
Out[16]:
0 1
0 -0.495847 -1.449251
1 -0.494721 1.572560
2 1.219985 0.280878
3 -0.419651 1.975562
4 -0.489689 -2.712342
5 -0.022466 -0.238129
6 -1.195269 -0.028390
7 -0.192648 1.220730
8 1.331892 0.950508
9 -0.790354 -0.743006
0 -0.761820 0.847983
1 -0.126829 1.304889
2 0.667949 -1.481652
3 0.030162 -0.111911
4 -0.433762 -0.596412
5 -1.110968 0.411241
6 -0.428930 0.086527
7 -0.866701 -1.286884
8 -0.649420 0.227999
9 -0.100669 -0.205232
[20 rows x 2 columns]
In [17]: store.close()
不过要记住,如果我在做这个的话,数据相同的情况下没有必要使用不同的节点;把它们放在一个表里会更有效率,比如可以加一个字段来表示它的名字、ID或者其他什么的。
我几乎总是对不同类型的数据使用不同的节点(不一定是不同的数据类型,但确实是不同“类型”的数据)。
话虽如此,你可以按照你喜欢的方式来组织数据!