快速有效的从HDF5文件序列化和检索大量numpy数组的方法

时间:2018-10-27 20:32:03

标签: python numpy hdf5 h5py numpy-ndarray

我有大量的numpy数组,特别是113287,其中每个数组的形状为36 x 2048。就内存而言,这等于 32 Gigabytes

到目前为止,我已经将这些阵列序列化为一个巨型HDF5文件。现在,问题在于,每次访问都需要从此hdf5文件中检索单个阵列,而这要花费非常长的时间(不到10分钟)。

如何加快速度?这对于我的实现非常重要,因为我必须索引该列表数千次才能馈入深度神经网络。

这是我索引到hdf5文件的方式:

In [1]: import h5py
In [2]: hf = h5py.File('train_ids.hdf5', 'r')

In [5]: list(hf.keys())[0]
Out[5]: 'img_feats'

In [6]: group_key = list(hf.keys())[0]

In [7]: hf[group_key]
Out[7]: <HDF5 dataset "img_feats": shape (113287, 36, 2048), type "<f4">


# this is where it takes very very long time
In [8]: list(hf[group_key])[-1].shape
Out[8]: (36, 2048)

有什么想法可以加快速度吗?还有其他方法可以序列化这些数组以加快访问速度吗?

注意:我使用的是Python列表,因为我希望保留顺序(即以与创建hdf5文件时的顺序相同的顺序进行检索)

2 个答案:

答案 0 :(得分:1)

一种方法是将每个样本放入自己的组中,然后直接将其编入索引。我认为转换需要很长时间,因为它试图将整个数据集加载到列表中(必须从磁盘读取)。重新整理h5文件,以使

    • 样本
      • 36 x 2048 可能有助于提高索引速度。

答案 1 :(得分:1)

根据Out[7],“ img_feats”是一个大型3d数组。 (113287,36,2048)形状。

ds定义为数据集(不加载任何内容):

ds = hf[group_key]

x = ds[0]    # should be a (36, 2048) array

arr = ds[:]   # should load the whole dataset into memory.
arr = ds[:n]   # load a subset, slice 

根据h5py-reading-writing-data

  

HDF5数据集重新使用NumPy切片语法来读取和写入文件。切片规范直接转换为HDF5“ hyperlab”选择,并且是一种快速有效的访问文件中数据的方式

我看不到将其包装在list()中的任何意义;也就是说,将3d数组拆分为113287个2d数组的列表。 HDF5文件上的3d数据集与numpy数组之间存在清晰的映射。

h5py-fancy-indexing警告说,数据集的奇特索引慢。也就是说,寻求加载该大型数据集的[1,1000,3000,6000]个子数组。

如果使用这么大的数据集过于混乱,您可能想尝试编写和读取一些较小的数据集。