[英]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.