将HDF5文件读入numpy数组

时间:2017-10-13 15:14:14

标签: python numpy hdf5 h5py

我有以下代码将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以查看存储在其中的数据?

6 个答案:

答案 0 :(得分:6)

最简单的方法是使用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。这可以直接读取,但在这种情况下非常容易导致崩溃(我在这个设计的例子中做过几次)。获取名称和阅读更容易。

答案 1 :(得分:2)

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

手边的人是&#34; Reference&#34;。它是HDF5存储模型中的内部地址。

h5py将为您完成所有工作,而不会调用任何模糊的例程,因为它会尝试尽可能多地遵循类似dict的界面(但对于引用,使其透明有点复杂)。 / p>

在文档中查找的位置是Object and Region References。它声明要访问引用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[:]

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

ds = hf[n1[0,0]]

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

data = ds[()]

一次获取所有数据集:

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

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

为了全面了解如何使用引用来往返数据,我写了一篇简短的编写程序&#34;和一个简短的阅读程序&#34;:

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语法作为参考数据集。这是因为NumPy数据类型无法表示HDF5引用。它们必须一次读写一个。

答案 2 :(得分:2)

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()

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

答案 3 :(得分:1)

这是将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)

答案 4 :(得分:1)

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

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]

答案 5 :(得分:0)

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

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