Pandas 和 h5py 以不同方式加载相同数据 (ndarray)
Pandas and h5py load the same data (ndarray) differently
我有一个 HDF5 格式的文件。它是使用 HDF5 的 C++ API 创建的,使用了这些:
struct SignalDefH5
{
char id [128];
char name [ 64];
char units[ 16];
float min;
float max;
hvl_t tags; /* This right there does not work in Pandas... */
};
struct TagDefH5
{
char tag [ 64];
char desc[256];
};
如果我使用 h5py 加载文件,我会得到:
>>> import h5py
>>> hfile = h5py.File('test.h5', 'r')
>>> signals = hfile['/signals']
>>> signals[0]
('id1', 'a pressure', 'bar', 0.0, 300.0, ['Pressure'])
>>> type(signals[0][5])
numpy.ndarray
但是,如果我使用 Pandas 加载同一个文件,我会得到:
>>> store = pd.HDFStore('test.h5')
>>> store.root.signals
/signals (Table(179,)) ''
description := {
"id": StringCol(itemsize=128, shape=(), dflt='', pos=0),
"name": StringCol(itemsize=64, shape=(), dflt='', pos=1),
"units": StringCol(itemsize=16, shape=(), dflt='', pos=2),
"min": Float32Col(shape=(), dflt=0.0, pos=3),
"max": Float32Col(shape=(), dflt=0.0, pos=4),
"tags": StringCol(itemsize=64, shape=(), dflt='', pos=5)}
byteorder := 'little'
chunkshape := (234,)
>>> store.root.signals[0]
('id1', 'a pressure', 'bar', 0.0, 300.0, '\x02\x00\x00\x00\x00\x00\x00\x00\xf0f\x1e\x04\x00\x00\x00\x00\xba\nVT\xd1!\xa7\xdd\xb0\xe3\x9a\x02\x00\x00\x00\x00@\xecR\x1f\xa2\x7f\x00\x00}B\x178\x96\xa4u\xe6\xb0\xdd\x7f\x02\x00\x00\x00\x00 \x01')
>>> type(store.root.signals[0][5])
numpy.string_
显然 Pandas 方式有问题:我做错了什么?
- Python 版本为 2.7.5.
- h5py版本为2.4.0.
- Pandas 版本为 0.16.0.
- PyTables 版本为 3.1.1。
Pandas HDF5 支持使用 PyTables
。这在顶部提供了一个元数据层,它本身(意思是 PyTables)在原始 HDF5 之上。 h5py
是非常原始的 HDF5。
因此 pandas 不知道该子字段,例如它实际上是什么。您正在获取原始字节字符串。
根本不支持像这样的嵌套结构。这些不能很好地映射到 pandas 结构。此外,通过在原始 HDF5 中创建此文件,您会丢失许多 pandas 需要解释数据的元数据。
只需使用PyTables/pandas
写入您的数据。然后,您可以也许 在 C++ 中对这种格式进行逆向工程。
我有一个 HDF5 格式的文件。它是使用 HDF5 的 C++ API 创建的,使用了这些:
struct SignalDefH5
{
char id [128];
char name [ 64];
char units[ 16];
float min;
float max;
hvl_t tags; /* This right there does not work in Pandas... */
};
struct TagDefH5
{
char tag [ 64];
char desc[256];
};
如果我使用 h5py 加载文件,我会得到:
>>> import h5py
>>> hfile = h5py.File('test.h5', 'r')
>>> signals = hfile['/signals']
>>> signals[0]
('id1', 'a pressure', 'bar', 0.0, 300.0, ['Pressure'])
>>> type(signals[0][5])
numpy.ndarray
但是,如果我使用 Pandas 加载同一个文件,我会得到:
>>> store = pd.HDFStore('test.h5')
>>> store.root.signals
/signals (Table(179,)) ''
description := {
"id": StringCol(itemsize=128, shape=(), dflt='', pos=0),
"name": StringCol(itemsize=64, shape=(), dflt='', pos=1),
"units": StringCol(itemsize=16, shape=(), dflt='', pos=2),
"min": Float32Col(shape=(), dflt=0.0, pos=3),
"max": Float32Col(shape=(), dflt=0.0, pos=4),
"tags": StringCol(itemsize=64, shape=(), dflt='', pos=5)}
byteorder := 'little'
chunkshape := (234,)
>>> store.root.signals[0]
('id1', 'a pressure', 'bar', 0.0, 300.0, '\x02\x00\x00\x00\x00\x00\x00\x00\xf0f\x1e\x04\x00\x00\x00\x00\xba\nVT\xd1!\xa7\xdd\xb0\xe3\x9a\x02\x00\x00\x00\x00@\xecR\x1f\xa2\x7f\x00\x00}B\x178\x96\xa4u\xe6\xb0\xdd\x7f\x02\x00\x00\x00\x00 \x01')
>>> type(store.root.signals[0][5])
numpy.string_
显然 Pandas 方式有问题:我做错了什么?
- Python 版本为 2.7.5.
- h5py版本为2.4.0.
- Pandas 版本为 0.16.0.
- PyTables 版本为 3.1.1。
Pandas HDF5 支持使用 PyTables
。这在顶部提供了一个元数据层,它本身(意思是 PyTables)在原始 HDF5 之上。 h5py
是非常原始的 HDF5。
因此 pandas 不知道该子字段,例如它实际上是什么。您正在获取原始字节字符串。
根本不支持像这样的嵌套结构。这些不能很好地映射到 pandas 结构。此外,通过在原始 HDF5 中创建此文件,您会丢失许多 pandas 需要解释数据的元数据。
只需使用PyTables/pandas
写入您的数据。然后,您可以也许 在 C++ 中对这种格式进行逆向工程。