0

我正在尝试从 hdf5 文件中读取数据 - 我之前使用 recarray 保存到它。一行数据的类型如下:2x u2(flags) 后跟 2x u4(timestamps) 和 32x u2(data)。

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 in range(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 倍。

4

2 回答 2

0

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

请注意如何print (arr#.dtype)特定于切片数据(arr1.dtype不同于arr2.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)
于 2019-08-13T22:11:54.817 回答
0

我认为使用具有复合 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)
于 2019-08-12T15:07:49.487 回答