将 HDF5 文件读入 numpy 数组

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

我有以下代码将 hdf5 文件读取为 numpy 数组:

hf = h5py.File('path/to/file', 'r')
n1 = hf.get('dataset_name')
n2 = np.array(n1)

当我打印

n2
时,我得到这个:

Out[15]:
array([[<HDF5 object reference>, <HDF5 object reference>,
        <HDF5 object reference>, <HDF5 object reference>...

如何读取

HDF5 object reference
来查看其中存储的数据?

python numpy hdf5 h5py
7个回答
38
投票

最简单的是使用 HDF5 数据集的

.value
属性。

>>> hf = h5py.File('/path/to/file', 'r')
>>> data = hf.get('dataset_name').value # `data` is now an ndarray.

您还可以对数据集进行切片,这会生成包含请求数据的实际 ndarray:

>>> hf['dataset_name'][:10] # produces ndarray as well

但请记住,在很多方面,

h5py
数据集的行为就像
ndarray
。因此,您可以将数据集本身不变地传递给大多数(如果不是全部)NumPy 函数。例如,这样就可以了:
np.mean(hf.get('dataset_name'))

编辑:

我最初误解了这个问题。问题不在于加载数值数据,而在于数据集实际上包含 HDF5 引用。这是一个奇怪的设置,读起来有点尴尬

h5py
。您需要取消引用数据集中的每个引用。我只展示其中一个。

首先,我们创建一个文件和一个临时数据集:

>>> f = h5py.File('tmp.h5', 'w')
>>> ds = f.create_dataset('data', data=np.zeros(10,))

接下来,创建对其的引用并将其中一些存储在数据集中。

>>> ref_dtype = h5py.special_dtype(ref=h5py.Reference)
>>> ref_ds = f.create_dataset('data_refs', data=(ds.ref, ds.ref), dtype=ref_dtype)

然后,您可以通过获取其名称,以迂回的方式读回其中一个,然后从引用的实际数据集中读取。

>>> name = h5py.h5r.get_name(ref_ds[0], f.id) # 2nd argument is the file identifier
>>> print(name)
b'/data'
>>> out = f[name]
>>> print(out.shape)
(10,)

虽然迂回,但似乎有效。 TL;DR 是:获取引用数据集的名称,并直接从中读取。

注:

尽管有这个名字,但

h5py.h5r.dereference
函数在这里似乎没什么帮助。它返回引用对象的 ID。这可以直接读取,但在这种情况下很容易导致崩溃(我在这个人为的示例中做了几次)。获取名称并从中读取要容易得多。

注2:

如 h5py 2.1

的发行说明中所述,不推荐使用

Dataset.value 属性,应根据需要使用 mydataset[...]

mydataset[()]
 进行替换。
属性 

Dataset.value
可以追溯到 h5py 1.0,已被弃用,并将在以后的版本中删除。此属性将整个数据集转储到 NumPy 数组中。使用

.value

 的代码应更新为使用 NumPy 索引,并酌情使用 
mydataset[...]
mydataset[()]
    

这是将 hdf5 文件读取为 numpy 数组的直接方法:

18
投票
import numpy as np import h5py hf = h5py.File('path/to/file.h5', 'r') n1 = np.array(hf["dataset_name"][:]) #dataset_name is same as hdf5 object name print(n1)

h5py 为此类任务提供了内在方法:

8
投票

hf = h5py.File('path/to/file', 'r')
n1 = np.zeros(shape, dtype=numpy_type)
hf['dataset_name'].read_direct(n1)
hf.close()

如果您
n1 = np.array(hf['dataset_name'])
,组合步骤仍然比

%timeit

更快。唯一的缺点是,需要事先知道数据集的形状,数据提供者可以将其指定为属性。

HDF5 有一个简单的对象模型,用于存储

6
投票
(粗略地说,相当于“文件数组”)并将它们组织成组(想想目录)。除了这两种对象类型之外,还有更强大的功能需要层层理解。

手头的是“参考

”。它是HDF5存储模型中的内部地址。

h5py 将为您完成所有工作,而无需调用任何晦涩的例程,因为它尝试尽可能遵循类似字典的界面(但对于参考,使其透明有点复杂)。

在文档中查找的位置是

对象和区域引用

。它指出要访问引用指向的对象

ref,你需要

 my_object = my_file[ref]

您的问题有两个步骤: 1. 获取参考 2.获取数据集

# Open the file hf = h5py.File('path/to/file', 'r') # Obtain the dataset of references n1 = hf['dataset_name'] # Obtain the dataset pointed to by the first reference ds = hf[n1[0]] # Obtain the data in ds data = ds[:]

例如,如果包含引用的数据集是二维的,则必须使用

ds = hf[n1[0,0]]

如果数据集是标量,则必须使用

data = ds[()]

一次性获取所有数据集:

all_data = [hf[ref] for ref in n1[:]]

假设 n1 为一维数据集。对于 2D,这个想法是成立的,但我没有看到一个简短的方法来编写它。

为了全面了解如何通过引用往返数据,我编写了简短的“编写器程序”和简短的“读取器程序”:

import numpy as np import h5py # Open file myfile = h5py.File('myfile.hdf5', 'w') # Create dataset ds_0 = myfile.create_dataset('dataset_0', data=np.arange(10)) ds_1 = myfile.create_dataset('dataset_1', data=9-np.arange(10)) # Create a data ref_dtype = h5py.special_dtype(ref=h5py.Reference) ds_refs = myfile.create_dataset('ref_to_dataset', shape=(2,), dtype=ref_dtype) ds_refs[0] = ds_0.ref ds_refs[1] = ds_1.ref myfile.close()


import numpy as np import h5py # Open file myfile = h5py.File('myfile.hdf5', 'r') # Read the references ref_to_ds_0 = myfile['ref_to_dataset'][0] ref_to_ds_1 = myfile['ref_to_dataset'][1] # Read the dataset ds_0 = myfile[ref_to_ds_0] ds_1 = myfile[ref_to_ds_1] # Read the value in the dataset data_0 = ds_0[:] data_1 = ds_1[:] myfile.close() print(data_0) print(data_1)

您会注意到,您无法对参考数据集使用标准的方便且简单的 NumPy 语法。这是因为 HDF5 引用无法用 NumPy 数据类型表示。它们必须一次一个地读取和写入。
    

嗨,这是我用来读取 hdf5 数据的方法,希望它对你有用

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

我尝试了之前建议的所有答案,但没有一个对我有用。
例如,read_direct() 方法给出错误“未为数据类型类定义操作”。 .value 方法也不起作用。经过一番努力,我可以使用引用本身来获取 numpy 数组。

1
投票
import numpy as np import h5py f = h5py.File('file.mat','r') data2get = f.get('data2get')[:] data = np.zeros([data2get.shape[1]]) for i in range(data2get.shape[1]): data[i] = np.array(f[data2get[0][i]])[0][0]

用于加载大型 .mat 文件,保存在版本 7.3 下的 MATLAB 中
即,如果您的 mat 文件使用“-v7.3”保存

0
投票
import numpy as np import h5py path = '/yourfile.mat' f = h5py.File(path)

类型:
list(f.keys())

列出您的数据。如果 mat 文件保存为“finance.mat”,则返回
['finance']

然后:

fin= f['finance'] fin_arr = np.asarray(fin)


© www.soinside.com 2019 - 2024. All rights reserved.