簡體   English   中英

將 HDF5 文件讀入 numpy 數組

[英]Read HDF5 file into numpy array

我有以下代碼可以將 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以查看其中存儲的數據?

最簡單的方法是使用 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[...]mydataset[()]替換。

可追溯到 h5py 1.0 的屬性Dataset.value已棄用,並將在以后的版本中刪除。 此屬性將整個數據集轉儲到 NumPy 數組中。 使用.value代碼應該更新為使用 NumPy 索引,根據需要使用mydataset[...]mydataset[()]

這是將 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)

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

如果你%timeit ,組合步驟仍然比n1 = np.array(hf['dataset_name'])快。 唯一的缺點是,需要事先知道數據集的形狀,數據提供者可以將其作為屬性分配。

HDF5 有一個簡單的對象模型,用於存儲數據集(粗略地說,相當於“文件數組”)並將它們組織成組(想想目錄)。 在這兩種對象類型之上,還有更強大的功能需要理解。

手頭的一個是“參考”。 它是 HDF5 存儲模型中的內部地址。

h5py 將為您完成所有工作,而無需調用任何晦澀的例程,因為它會嘗試盡可能多地遵循類似 dict 的界面(但對於引用而言,使其透明有點復雜)。

在文檔中查找的位置是Object 和 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[:]

例如,如果包含引用的數據集是二維的,則必須使用

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數據的方式,希望它對你有用

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

我嘗試了之前建議的所有答案,但沒有一個對我有用。 例如,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]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM