将HDF5文件读入numpy数组

e9e*_*e9s 8 python numpy hdf5 h5py

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

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

当我打印n2我得到这个:

Out[15]:
array([[<HDF5 object reference>, <HDF5 object reference>,
        <HDF5 object reference>, <HDF5 object reference>...
Run Code Online (Sandbox Code Playgroud)

如何阅读HDF5 object reference查看存储在其中的数据?

bna*_*ker 9

最简单的方法是使用.valueHDF5数据集的属性.

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

您还可以对数据集进行切片,从而生成具有所请求数据的实际ndarray:

>>> hf['dataset_name'][:10] # produces ndarray as well
Run Code Online (Sandbox Code Playgroud)

但请记住,在许多方面,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,))
Run Code Online (Sandbox Code Playgroud)

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

>>> ref_dtype = h5py.special_dtype(ref=h5py.Reference)
>>> ref_ds = f.create_dataset('data_refs', data=(ds.ref, ds.ref), dtype=ref_dtype)
Run Code Online (Sandbox Code Playgroud)

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

>>> 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,)
Run Code Online (Sandbox Code Playgroud)

这是圆形的,但似乎有效.TL; DR是:获取引用数据集的名称,并直接从中读取.

注意:

h5py.h5r.dereference尽管有名字,这个功能在这里看起来非常无益.它返回引用对象的ID.这可以直接读取,但在这种情况下容易导致崩溃(我在这个设计的例子中做过几次).获取名称和阅读更容易.


小智 9

这是将 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)
Run Code Online (Sandbox Code Playgroud)


Pie*_*uyl 6

HDF5 有一个简单的对象模型,用于存储数据集(粗略地说,相当于“文件数组”)并将它们组织成组(想想目录)。除了这两种对象类型之外,还有更强大的功能需要层层理解。

手头有一份“参考资料”。它是HDF5存储模型中的内部地址。

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

在文档中查找的位置是“对象和区域引用”。它指出要访问通过引用指向的对象ref,您需要

 my_object = my_file[ref]
Run Code Online (Sandbox Code Playgroud)

在您的问题中,有两个步骤: 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[:]
Run Code Online (Sandbox Code Playgroud)

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

ds = hf[n1[0,0]]
Run Code Online (Sandbox Code Playgroud)

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

data = ds[()]
Run Code Online (Sandbox Code Playgroud)

要一次性获取所有数据集:

all_data = [hf[ref] for ref in n1[:]]
Run Code Online (Sandbox Code Playgroud)

假设 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()
Run Code Online (Sandbox Code Playgroud)

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)
Run Code Online (Sandbox Code Playgroud)

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


Arc*_*rEX 6

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

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

组合的步骤仍然比n1 = np.array(hf['dataset_name'])您更快%timeit。唯一的缺点是,需要事先知道数据集的形状,数据提供者可以将其作为属性分配。


Yan*_*eux 5

您好,这是我用来读取 hdf5 数据的方式,希望对您有用

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