将HDF5文件读入numpy数组

2024-05-17 03:19:06 发布

您现在位置:Python中文网/ 问答频道 /正文

我有以下代码以numpy数组的形式读取hdf5文件:

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以查看其中存储的数据?


Tags: 文件代码numpyobject数组array形式file
3条回答

最简单的是使用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 is:获取被引用数据集的名称,并直接从中读取。

注意:

尽管有这个名字,h5py.h5r.dereference函数在这里似乎很没用。它返回被引用对象的ID。这可以直接从中读取,但在这种情况下,很容易导致崩溃(在这个人为的例子中,我做了好几次)。从中得到名字和阅读要容易得多。

HDF5有一个简单的对象模型,用于存储datasets(粗略地说,相当于一个“文件数组”)并将它们组织成组(考虑目录)。在这两种对象类型之上,还有更强大的特性,需要理解层。

手边的是一个“Reference”。它是HDF5存储模型中的一个内部地址。

h5py将为您完成所有的工作,而不需要调用任何模糊的例程,因为它试图尽可能多地遵循类似dict的接口(但对于引用,使其透明会更复杂一些)。

在文档中查找的位置是Object and Region References。它声明要访问通过引用指向的对象ref,您需要

 my_object = my_file[ref]

在你的问题中,有两个步骤: 一。获取参考 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为1D数据集。对于2D来说,这个想法是可行的,但我认为没有捷径可以写出来。

为了全面了解如何使用引用来回访问数据,我编写了一个简短的“writer程序”和一个简短的“reader程序”:

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文件作为numpy数组读取的直接方法:

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)

相关问题 更多 >