读取大型 .h5 文件时出现内存错误

Memory error while reading a large .h5 file

我已经从 numpy 数组创建了一个 .h5

h5f = h5py.File('/data/debo/jetAnomaly/AtlasData/dijets/mergedRoot/miniTrees/JZ3W.h5', 'w')
h5f.create_dataset('JZ3WPpxpypz', data=all, compression="gzip")

HDF5 数据集 "JZ3WPpxpypz":形状 (19494500, 376),类型 "f8"

但是我在将 .h5 文件读取到 numpy 数组时出现内存错误

filename = '/data/debo/jetAnomaly/AtlasData/dijets/mergedRoot/miniTrees/JZ3W.h5'
h5 = h5py.File(filename,'r')

h5.keys()

[u'JZ3WPpxpypz']

data = h5['JZ3WPpxpypz']

如果我尝试查看数组,它会给我内存错误

data[:]

---------------------------------------------------------------------------
MemoryError                               Traceback (most recent call last)
<ipython-input-33-629f56f97409> in <module>()
----> 1 data[:]

h5py/_objects.pyx in h5py._objects.with_phil.wrapper()

h5py/_objects.pyx in h5py._objects.with_phil.wrapper()

/home/debo/env_autoencoder/local/lib/python2.7/site-packages/h5py/_hl/dataset.pyc in __getitem__(self, args)
    560         single_element = selection.mshape == ()
    561         mshape = (1,) if single_element else selection.mshape
--> 562         arr = numpy.ndarray(mshape, new_dtype, order='C')
    563 
    564         # HDF5 has a bug where if the memory shape has a different rank

MemoryError: 

是否有任何内存有效的方法将 .h5 文件读入 numpy 数组?

谢谢, 德博.

您不需要调用 numpy.ndarray() 来获取数组。 试试这个:

arr = h5['JZ3WPpxpypz'][:]
# or
arr = data[:]

添加 [:] returns 数组(与您的 data 变量不同——它只是引用 HDF5 数据集)。这两种方法都应该为您提供与原始数组具有相同数据类型和形状的数组。您还可以使用 numpy 切片操作来获取数组的子集。

需要澄清一下。我忽略了 numpy.ndarray() 作为打印 data[:] 过程的一部分被调用。 以下是类型检查,以显示来自 2 个调用的 returns 的差异:

# check type for each variable:
data = h5['JZ3WPpxpypz']
print (type(data))
# versus
arr = data[:]
print (type(arr))

输出将如下所示:

<class 'h5py._hl.dataset.Dataset'>
<class 'numpy.ndarray'>

一般来说,h5py 数据集的行为类似于 numpy 数组(按设计)。 但是,它们并不相同。当您尝试使用此调用 (data[:]) 打印数据集内容时,h5py 尝试在后台使用 numpy.ndarray() 将数据集转换为 numpy 数组。如果您有较小的数据集或足够的内存,它会起作用。

我的收获:调用 arr = h5['JZ3WPpxpypz'][:] 使用不调用 numpy.ndarray().

的进程创建 numpy 数组

当您拥有非常大的数据集时,您可能会 运行 遇到无法使用 arr= h5f['dataset'][:] 创建数组的情况,因为数据集太大而无法作为 numpy 数组放入内存。发生这种情况时,您可以创建 h5py 数据集对象,然后使用切片符号访问数据的子集,就像这个简单的例子:

data = h5['JZ3WPpxpypz']
arr1 = data[0:100000]
arr2 = data[100000:200000])
# etc