将NumPy数组输入和输出到h5py

120
我有一段Python代码,它的输出是一个大小为 enter image description here 的矩阵,其所有元素都是 float 类型。如果我将其保存为扩展名为 .dat 的文件,文件大小约为 500 MB。我了解到使用 h5py 可以显著减小文件大小。那么,假设我有名为 A 的 2D numpy 数组。如何将其保存到一个 h5py 文件中? 另外,如何读取相同的文件并将其作为 numpy 数组放入不同的代码中,因为我需要对数组进行操作?

4
你是如何使用.dat扩展名来保存它的? - jorgeca
@jorgeca:为此,我只需执行np.savetxt("output.dat",A,'%10.8e') - lovespeed
3
谢谢(仅扩展名并不意味着太多,它可以存储为二进制、ASCII等格式...)。除非您需要hdf5的额外功能,否则我建议使用np.save('output.dat', A)将其保存为二进制格式(速度更快,占用空间更少)。 - jorgeca
当然,只需删除 txt 和解包参数即可。 - jorgeca
2
那么 h5py 不会创建比 np.save 更小的文件吗?对于问题中给定大小的数组,h5py 是否比 np.save 更快? - abcd
显示剩余2条评论
2个回答

154

h5py提供了关于数据集和组的模型。数据集基本上是数组,组可以看作是目录。每个都有名称。您应该查看API文档和示例:

http://docs.h5py.org/en/latest/quick.html

一个简单的例子,您可以在其中预先创建所有数据,并只想将其保存到HDF5文件中,可能如下所示:

In [1]: import numpy as np
In [2]: import h5py
In [3]: a = np.random.random(size=(100,20))
In [4]: h5f = h5py.File('data.h5', 'w')
In [5]: h5f.create_dataset('dataset_1', data=a)
Out[5]: <HDF5 dataset "dataset_1": shape (100, 20), type "<f8">

In [6]: h5f.close()

你可以使用以下代码重新加载数据:

In [10]: h5f = h5py.File('data.h5','r')
In [11]: b = h5f['dataset_1'][:]
In [12]: h5f.close()

In [13]: np.allclose(a,b)
Out[13]: True

一定要查看文档:

http://docs.h5py.org

写入hdf5文件取决于h5py或pytables(每个API都有不同的Python API,它们位于hdf5文件规范之上)。 您还应该查看由numpy本地提供的其他简单二进制格式,例如np.savenp.savez等:

http://docs.scipy.org/doc/numpy/reference/routines.io.html


顺便说一下,如果在阅读时不知道数据集的名称,则必须类似于这里对hdf文件进行解析。 (https://dev59.com/fFsX5IYBdhLWcg3wB7n3) - Trilarion
@JoshAdel 如果我想向数据集添加列,我的数据集是一个多维 np.array,索引为 [img_id,rows,colums,channels]。 我已经使用您的答案中描述的方法保存了它。我使用 h5f ['dataset_1'] [img_id] 访问数据集中的所有点。 我想要的是一种方法,可以添加另一列,例如“mycolumn”... 对应于数据集中的每个 img_id。 我该如何添加另一列,以便我可以执行 h5f ['mycolumn'] [img_id]? - Irtaza
如果我像这样编写矩阵,那么我无法在HDFView 2.11中查看它们 - 我可以打开文件,可以看到数据集“data.h5”存在,但我无法使用HDFView查看它。我可以使用h5py读取内容,但无法使用HDFView进行检查。有任何想法为什么会这样吗? - Martin Thoma

138

更加简洁的方式来处理文件的打开、关闭和避免内存泄漏:

准备工作:

import numpy as np
import h5py

data_to_write = np.random.random(size=(100,20)) # or some such

写:

with h5py.File('name-of-file.h5', 'w') as hf:
    hf.create_dataset("name-of-dataset",  data=data_to_write)

阅读:

with h5py.File('name-of-file.h5', 'r') as hf:
    data = hf['name-of-dataset'][:]

2
不需要关闭文件吗? - ricoamor
26
@DrDeSancho 不是,with语句 - Leonid
1
特别是在交互模式下运行时非常有用(否则,如果重新运行相同的代码而没有正确关闭第一次尝试中已经打开的文件,则可能会从h5py获得异常)。 - Andre Holzner
1
Python的with特性被称为上下文管理器。它将确保文件在使用后被关闭。更多信息可在官方文档中找到:https://docs.python.org/3/library/contextlib.html - moo
要读取标量值,请使用 hf['name-of-scalar'][()],否则您将得到一个 ValueError: Illegal slicing argument for scalar dataspace - MrCrHaM

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接