使用 h5py 保存混合结构化数据

Posted

技术标签:

【中文标题】使用 h5py 保存混合结构化数据【英文标题】:Saving mixed structured data with h5py 【发布时间】:2020-02-28 15:07:00 【问题描述】:

我有一个包含 100,000 个条目的数据集,每个表单:


attr1 float[300]
attr2 float[300]
attr3 float[300]
attr4 float
attr5 float
attr6 float

将其存储在.hdf5 文件中的最有效方法是什么?

【问题讨论】:

您有 2 个(至少)选择使用 Python:PyTables(又名表)或 h5py 写入/读取 HDF5 文件。您的示例有些微不足道,两者都可以完成工作。更大的问题是您打算如何处理数据。这会影响您应该如何组织数据。您想将所有数据保存在一个数据集中吗?使用 PyTables,您可以创建一个包含 100,000 行的表。每行将有 6 个列/字段,每个都有不同的对象类型。 是的,具有 100,000 行的单个数据集是理想的。 【参考方案1】:

没有您的数据(和数据结构)或代码示例,很难提供针对您的问题的示例。我创建了一个显示基本操作的 PyTables 示例。定义表结构和输入数据的方法有很多种。我喜欢创建一个np.dtype 并引用description=。在此示例中,我使用具有一个元组的列表逐行创建和添加数据。但是,如果您拥有所有数据,则可以创建一个 NumPy 结构化数组并使用 obj= 参数进行引用。这将创建数组并一次性填充所有内容

这是 PyTables 示例,它有 100 行和 attr1/2/3 数组,大小为 10 个元素。它显示了逻辑。您可以修改以增加行数和数组元素。

这里解释了所有 PyTables 表方法:PyTables table methods

import tables as tb
import numpy as np

attr1  = np.arange(10.)
attr2  = 2.0*np.arange(10.)
attr3  = 3.0*np.arange(10.)
attr4  = 4.0
attr5  = 5.0
attr6  = 6.0

ds_dt = np.dtype('names':['attr1', 'attr2', 'attr3',
                           'attr4', 'attr5', 'attr6'],
                  'formats':[(float,10), (float,10), (float,10),
                              float, float, float ] ) 

with tb.File('SO_58674120_tb.h5','w') as h5f:

     tb1 = h5f.create_table('/','my_ds', description=ds_dt)
     for rcnt in range(1,100):
         data_list = [ (rcnt*attr1, rcnt*attr2, rcnt*attr3,
                        rcnt*attr4, rcnt*attr5, rcnt*attr6), ]
         tb1.append(data_list)

您可以对h5py 执行相同的操作。过程类似,但也有区别。例如,您必须使用shape= 调整数据集的大小,如果您想在将来扩展数据集,请添加maxshape=。另外,我只知道如何通过引用 numpy 数组(而不是 PyTables 之类的列表)来添加数据。所以我创建了recarr 来保存中间数据。同样,如果您拥有所有数据,则不必逐行加载。

见下面的代码:

import h5py
import numpy as np

attr1  = np.arange(10.)
attr2  = 2.0*np.arange(10.)
attr3  = 3.0*np.arange(10.)
attr4  = 4.0
attr5  = 5.0
attr6  = 6.0

ds_dt = np.dtype('names':['attr1', 'attr2', 'attr3',
                           'attr4', 'attr5', 'attr6'],
                  'formats':[(float,10), (float,10), (float,10),
                              float, float, float ] ) 
recarr = np.empty((1,), dtype=ds_dt)

with h5py.File('SO_58674120_h5.h5','w') as h5f:

     h5f.create_dataset('my_ds', dtype=ds_dt, shape=(100,), maxshape=(None) )
     for rcnt in range(1,100):
         recarr['attr1']= rcnt*attr1
         recarr['attr2']= rcnt*attr2
         recarr['attr3']= rcnt*attr3
         recarr['attr4']= rcnt*attr4
         recarr['attr5']= rcnt*attr5
         recarr['attr6']= rcnt*attr6
         h5f['my_ds'][rcnt] = recarr[0]

【讨论】:

非常感谢您的解决方案。所以诀窍是使用np.dtype(),非常方便。我将比较这两种方法,然后希望标记为正确答案 我在创建表格时使用了np.dtype(),因为我在创建表格后添加了数据。如果您的所有数据都在 1 个记录数组中,您可以使用 h5py 将其引用为 data=,或者使用 pytables 将其引用为 obj=。 dtype 将从记录数组中推断出来。

以上是关于使用 h5py 保存混合结构化数据的主要内容,如果未能解决你的问题,请参考以下文章

使用h5py(或其他方法)有效保存和加载数据

使用不同大小的 h5py 数组保存

使用 h5py 沿新轴将数据添加到现有 h5py 文件

查询 SQL + HDF5 混合

是否可以使用 python 3 对 h5py 中的键进行切片而不形成列表?

具有版本控制的 HDF5 文件 (h5py) - 每次保存时都会更改哈希