python - h5py:如何组织 HDF5 文件以有效读取混合数据类型对象
问题描述
我目前正在使用 python3.x 并使用 h5py 库来写入/读取 HDF5 文件。
假设我有大量包含混合数据类型属性的元素。我想将它们存储在 HDF5 文件中,以便可以通过索引尽可能有效地读取单个元素。
例如,假设我有以下数据:
item_1 = {'string_name': 'Paul', 'float_height': 5.9, 'int_age':27, 'numpy_data': np.array([5.4, 6.7, 8.8])}
item_2 = {'string_name': 'John', 'float_height': 5.7, 'int_age':31, 'numpy_data': np.array([3.1, 58.4, 66.4])}
...
item_1000000 = {'string_name': 'Anna', 'float_height': 6.1, 'int_age':33, 'numpy_data': np.array([4.7, 5.1, 4.2])}
我发现的最简单的解决方案是将每个属性存储在一个单独的数组中,然后将每个数组分别存储在 HDF5 文件中。
string_names = ['Paul', 'John', ... , 'Anna']
float_heights = [5.9, 5.7, ... , 6.1]
int_ages = [27, 31, ... , 33]
numpy_data = big_numpy_array_of_shape_1000000_by_3
然后,作为示例,要检索第三个元素,我必须为四个数组中的每一个读取索引“2”处的元素。
这个解决方案工作得很好,但我的猜测是它是一个非常低效的解决方案,因为需要四个读取操作来检索每个元素。
有什么建议么?
解决方案
正如@hpaulj 指出的那样,关键是创建一个记录数组(和/或dtype)并在创建数据集时引用。有很多方法可以加载数据。我使用您的列表数据(如下)创建了一个示例,该示例显示了最简单的 2 个(恕我直言)。阅读所有方法的参考资料。我不确定您是否可以从字典中加载。我确信有足够的 Python 和 NumPy 魔法是可能的。
import h5py
import numpy as np
string_names = ['Paul', 'John', 'Anna']
float_heights = [5.9, 5.7, 6.1]
int_ages = [27, 31, 33]
numpy_data = [ np.array([5.4, 6.7, 8.8]),
np.array([3.1, 58.4, 66.4]),
np.array([4.7, 5.1, 4.2]) ]
# Create empty record array with 3 rows
ds_dtype = [('name','S50'), ('height',float), ('ages',int), ('numpy_data', float, (3,) ) ]
ds_arr = np.recarray((3,),dtype=ds_dtype)
# load list data to record array by field name
ds_arr['name'] = np.asarray(string_names)
ds_arr['height'] = np.asarray(float_heights)
ds_arr['ages'] = np.asarray(int_ages)
ds_arr['numpy_data'] = np.asarray(numpy_data)
with h5py.File('SO_59483094.h5', 'w') as h5f:
# load data to dataset my_ds1 using recarray
dset = h5f.create_dataset('my_ds1', data=ds_arr, maxshape=(None) )
# load data to dataset my_ds2 by lists/field names
dset = h5f.create_dataset('my_ds2', dtype=ds_dtype, shape=(100,), maxshape=(None) )
dset['name',0:3] = np.asarray(string_names)
dset['height',0:3] = np.asarray(float_heights)
dset['ages',0:3] = np.asarray(int_ages)
dset['numpy_data',0:3] = np.asarray(numpy_data)
推荐阅读
- bamboo - 在 Bamboo 的远程主机上运行并发构建
- javascript - 如何使用 setState 在 Redux 上为 onLoad 设置初始值
- sql - 传递列名时报告参数不起作用
- javascript - ElectronJS - 读取另一个应用程序的内容,例如不相关的 Chrome 窗口的 Web 内容
- javascript - 如何将元素保持在浮动元素之下?
- internet-explorer - DotNetNuke 中的 IE 11 重复 X-UA 兼容标签
- objectify - 在获取光标之前是否需要使用对象化迭代器?
- python - 如何获得使用 GridSearchCV 尝试的每个模型的 F1 分数和准确度?
- java - 选项菜单在所有活动中可用
- android - Cordova facebook 插件无效的密钥哈希