为什么不修复HDF5废弃警告,只能处理大文件?

问题描述 投票:0回答:1

在收到 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

工作得很好,除了发出的警告... ...

为什么我的代码能正常工作?

python arrays numpy machine-learning hdf5
1个回答
1
投票

让我解释一下你的代码在做什么,为什么你会出现内存错误。首先是一些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,:,:,:] 
© www.soinside.com 2019 - 2024. All rights reserved.