如何从保存为不同类型的注册表阵列的hdf5(h5py)中读取数据?



我正在尝试从hdf5文件中读取数据 - 我以前使用recarray保存到它。 一行数据的类型如下:2x u2(标志(,后跟 2x u4(时间戳(和 32x u2(数据(。

self.flags = np.empty((self.size, 2), dtype="u2")
self.t0 = np.empty(self.size, dtype="u4")
self.t1 = np.empty(self.size, dtype="u4")
self.data = np.empty((self.size, 32), dtype="u2")
...
labels = ['lost events','overwritten events', 't0', 't1'] + ["data_{0}".format(i) for i in range(32)]
result_arr = np.rec.fromarrays(tuple(self.flags.T)+(self.t0, self.t1) + tuple(self.data.T), names=labels)
file.create_dataset('dataset_name', data=result_arr)

现在我想逐行迭代该文件的一部分(数据部分 - 最后 32 列(,并能够像通常的 numpy.array 一样处理它。

data = self.dataset[row_n]
def parseDataToFlags(data):
return np.array(list(data)[4:36], dtype="u2")

这正在工作,但速度非常慢。我正在寻找一种正确的方法来做到这一点,因为我将处理大数据文件。 我也试图搞砸这个:(self.dataset是从文件加载的h5py数据集(

def get(self, index):
if not (0 <= index < self.n_of_rows):
raise IndexError
return type(self.dataset['t0', 't1'][index])

但是当我尝试将 [data_{0}".format(i( for i 放在范围 (32(] 中代替"t0"、"t1"时,它失败了。

我做了几次尝试将数据解析为结构化数组,但到目前为止没有运气。

我应该如何正确尝试阅读过程?我应该更改访问顺序(列后行(还是有办法在读取行后将这些数据解析为正确的类型?

更新 我得到了一些帮助,结果如下: 我的代码中如此缓慢的不是创建列表并为每一行解析为 numpy 数组。访问h5py文件中的数据是。因此,最好访问一次并一次解析它们。

self.flags = np.vstack((self.dataset['lost events'], self.dataset['overwritten events'])).T
self.time = np.vstack((self.dataset['t0'], self.dataset['t1'])).T
self.output = np.vstack([self.dataset['data_'+str(i)] for i in range(32)]).T

一旦我使用它,代码就会加速近 1000 倍。

我认为使用具有复合 dtype 的结构化数组您的任务会更简单,例如:

In [86]: dt = [('events','u2'),('t0','u4'),('t1','u4'),('data','u2',32)]                                     
In [87]: d = np.zeros(3, dt)                                                                                 
In [88]: d                                                                                                   
Out[88]: 
array([(0, 0, 0, [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]),
(0, 0, 0, [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]),
(0, 0, 0, [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])],
dtype=[('events', '<u2'), ('t0', '<u4'), ('t1', '<u4'), ('data', '<u2', (32,))])

data可以作为一个二维数组访问:

In [89]: d['data']                                                                                           
Out[89]: 
array([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0]], dtype=uint16)

这个答案扩展了hpaulj的例子。它添加更多字段和数据,创建 HDF5 文件,然后打开以按行#和/或字段名称进行读取和切片。我使用h5fwh5fr来显示我正在写入和读取不同的文件句柄/对象。通常我不会这样做。

请注意print (arr#.dtype)特定于切片数据(arr1.dtypearr2.dtype不同(。

import numpy as np
import h5py
# create HDF5 file and add a dataset:
with h5py.File('SO_57460643.h5','w') as h5fw:
labels = ['lost events','overwritten events', 't0', 't1'] + ["data_{0}".format(i) for i in range(4)]
dt = np.dtype({'names': labels,
'formats': ['u2']*2 + ['u4']*2 + ['u4']*4 })
nrows=5
ncols=8                                               
d = np.zeros(nrows, dt)
for row in range(nrows) :
arr_tup = tuple(range(row*ncols,(row+1)*ncols))
d[row] = arr_tup
#print (d)
h5fw.create_dataset('ds_name', data=d)
# open HDF5 for reading only:
with h5py.File('SO_57460643.h5','r') as h5fr:
#  get last row
arr1 = h5fr['ds_name'][-1]
print (arr1.dtype)
print (arr1)
#  get rows 1-3, fields t0, data_0, data_1, data_2, data_3
arr2 = h5fr['ds_name'][1:4,'t0', 'data_0', 'data_1', 'data_2', 'data_3']
print (arr2.dtype)
print (arr2)

最新更新