python - 为什么只有在不修复 HDF5 弃用警告时才能处理大文件?
问题描述
收到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
工作得很好,除了发出的警告..
为什么我的代码有效?
解决方案
让我解释一下您的代码在做什么,以及为什么会出现内存错误。首先是一些 HDF5/h5py 基础知识。(h5py 文档是一个很好的起点。在这里查看:h5py QuickStart)
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 切片表示法是从数据集对象返回 NumPy 数组的方法。正如您所发现的,.value
它已被弃用。)
这也返回一个 Numpy 数组:(data_foo = foo[()]
假设 foo 定义如上)。
因此,当您输入此等式时,data_foo = np.array(foo[()])
您正在从另一个数组(foo[()]
是输入对象)创建一个新的 NumPy 数组。我怀疑您的进程已被杀死,因为创建 (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,:,:,:]
推荐阅读
- python - 将图例添加到 plotWidget 时 CSVexporter 失败
- c# - XAML 中的 String.Format 与 Xamarin 表单中的本地化
- java - 刷新 Apache Beam/Dataflow 中的边输入
- css - 嵌套 flex 的 Edge+Firefox 高度问题
- python - 多处理:字典不是持久的
- javascript - Chrome中的画布drawImage
- javascript - axios + Vuex - 避免两次被拒绝承诺?
- linux - 使用 bash 打印数组中最大值的索引
- qt - Qt C++ 简单的 SMTP 客户端
- asp.net - 无法一致地设置 Telerik RadTextBox (v2013.3.1324.40) 边框和背景颜色