h5py:如何组织HDF5文件以有效读取混合数据类型对象

问题描述 投票:1回答:1

我目前正在使用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”的元素。

此解决方案工作得很好,但是我猜测这是一个非常低效的解决方案,因为需要四个读取操作才能检索每个元素。

有什么建议吗?

python numpy hdf5 h5py
1个回答
1
投票

正如@hpaulj指出的那样,关键是创建记录数组(和/或dtype)并在创建数据集时进行引用。有很多加载数据的方法。我使用您的列表数据(如下)创建了一个示例,该示例显示了最简单的2个(IMHO)。阅读所有方法的参考。我不确定是否可以从字典中加载。我相信使用足够多的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)
© www.soinside.com 2019 - 2024. All rights reserved.