在收到 H5pyDeprecationWarning: dataset.value has been deprecated. Use dataset[()] instead.
警告我把我的代码改成了:
import h5py
import numpy as np
f = h5py.File('myfile.hdf5', mode='r')
foo = f['foo']
bar = f['bar']
N, C, H, W = foo.shape. # (8192, 3, 1080, 1920)
data_foo = np.array(foo[()]) # [()] equivalent to .value
当我试图读取一个(不是那么)大的图片文件时,我得到了一个... ... Killed: 9
在我的终端上,我的进程被杀死了,因为它消耗了太多的内存,在代码的最后一行,尽管我在那里有一个陈旧的注释。.
然而,我的原始代码,
f = h5py.File('myfile.hdf5', mode='r')
data_foo = f.get('foo').value
# script's logic after that worked, process not killed
工作得很好,除了发出的警告... ...
为什么我的代码能正常工作?
让我解释一下你的代码在做什么,为什么你会出现内存错误。首先是一些HDF5h5py的基础知识。(h5py docs是一个很好的起点。请看这里。h5py快速入门)
foo = f['foo']
和 foo = f.get('foo')
都返回一个名为'foo'的h5py数据集对象(注意: 更常见的是将其看作是 foo = f['foo']
但没有任何问题 get()
方法)。) 一个数据集对象 不一样 作为一个NumPy数组。数据集的行为就像NumPy数组一样,两者都有一个形状和一个数据类型,并且支持数组式的分片。然而,当你访问一个数据集对象时,你并没有将所有的数据读入内存。因此,它们需要较少的内存来访问。在处理大型数据集时,这一点非常重要。
该语句返回一个Numpy数组。data_foo = f.get('foo').value
. 首选的方法是 data_foo = f['foo'][:]
. (NumPy slicing符号是从数据集对象中返回一个NumPy数组的方法。正如你发现的那样。.value
已被废弃。) 这也会返回一个Numpy数组。data_foo = foo[()]
(假设foo的定义如上). 所以,当你输入这个公式时 data_foo = np.array(foo[()])
你正在从另一个数组中创建一个新的NumPy数组(foo[()]
是输入对象)。) 我怀疑你的进程被杀死是因为创建一个(8192, 3, 1080, 1920)数组副本的内存量超过了你的系统资源。这句话对于小的数据集数组是可行的。但是,这不是好的做法。
这里有一个例子来展示如何使用不同的方法(h5py数据集对象与NumPy数组)。
h5f = h5py.File('myfile.hdf5', mode='r')
# This returns a h5py object:
foo_ds = h5f['foo']
# You can slice to get elements like this:
foo_slice1 = foo_ds[0,:,:,:] # first row
foo_slice2 = foo_ds[-1,:,:,:] # last row
# This is the recommended method to get a Numpy array of the entire dataset:
foo_arr = h5f['foo'][:]
# or, referencing h5py dataset object above
foo_arr = foo_ds[:]
# you can also create an array with a slice
foo_slice1 = h5f['foo'][0,:,:,:]
# is the same as (from above):
foo_slice1 = foo_ds[0,:,:,:]