Python 为什么只有在我没有';无法修复HDF5弃用警告?

Python 为什么只有在我没有';无法修复HDF5弃用警告?,python,arrays,numpy,machine-learning,hdf5,Python,Arrays,Numpy,Machine Learning,Hdf5,收到H5pyDeprecationWarning后:dataset.value已被弃用。改为使用数据集[()。,我将代码更改为: 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[()]) # [()]

收到
H5pyDeprecationWarning后:dataset.value已被弃用。改为使用数据集[()。
,我将代码更改为:

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
除了发出警告外,一切正常


为什么我的代码能工作?

让我解释一下您的代码在做什么,以及为什么会出现内存错误。首先是一些HDF5/h5py的基础知识。(h5py文档是一个很好的起点。请检查此处:)

foo=f['foo']
foo=f.get('foo')
都返回一个名为“foo”的h5py数据集对象(注意:更常见的情况是将其视为
foo=f['foo']
,但是
get()
方法没有错。)数据集对象与NumPy数组不同。数据集的行为类似于NumPy数组;两者都有一个形状和一个数据类型,并支持数组样式的切片。但是,当您访问dataset对象时,并没有将所有数据读入内存。因此,它们需要更少的内存来访问。这在处理大型数据集时非常重要

此语句返回一个Numpy数组:
data\u foo=f.get('foo')。value
。首选方法是
data\u foo=f['foo'][:]
。(NumPy切片表示法是从数据集对象返回NumPy数组的方法。正如您所发现的,
.value
不推荐使用。)
这还会返回一个Numpy数组:
data\u foo=foo[()]
(假设foo的定义如上所述)。
因此,当您输入这个等式时,
data\u foo=np.array(foo[()])
您正在从另一个数组创建一个新的NumPy数组(
foo[()]
是输入对象)。我怀疑您的进程被终止,因为创建(8192,3,1080,1920)阵列副本的内存量超过了您的系统资源。该语句适用于小型数据集/数组。然而,这不是一个好的做法

下面的示例演示如何使用不同的方法(h5py数据集对象与NumPy数组)


此行返回一个h5py对象:
foo=f['foo']
。数据集对象的行为类似于NumPy数组(例如,可以对foo进行切片)。如果需要NumPy数组,请在创建
foo
对象后使用
foo\u arr=f['foo'][:]
foo\u arr=foo[:]
。注意
.value()
的工作原理类似于
[:]
,但它是一种不推荐使用的方法。使用NumPy切片表示法。还有一件事……数据集对象比NumPy数组具有内存使用优势。与NumPy数组不同,当访问对象时,不会将整个数据集读取到内存中。创建对象,然后根据需要访问切片。你创建了一个包含所有数据的数组——这就是为什么你的进程占用了这么多内存。嗯,我想我明白你的意思了@kcw78,我不知道numpy和dataset对象之间的关键区别。如果你愿意,我相信你可以把你的评论变成一个答案。或者,如果你觉得我的问题没意思,我会删除它。你的问题对于强调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,:,:,:]