web-dev-qa-db-ja.com

HDF5ファイルをnumpy配列に読み込みます

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そこに保存されているデータを表示するには?

7
e9e9s

最も簡単なことは、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_を読むのはちょっと厄介です。データセット内の各参照をdereferenceする必要があります。そのうちの1つだけを紹介します。

最初に、ファイルと一時データセットを作成しましょう。

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

次に、その名前を取得し、参照されている実際のデータセットから読み取ることにより、これらの1つを逆方向に読み取ることができます。

_>>> 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を返します。これは直接読み取ることができますが、この場合はクラッシュを引き起こすのは簡単ですvery(ここでこの不自然な例で何度か行いました)。名前を取得してそこから読むのはずっと簡単です。

8
bnaecker

以下は、numpy配列としてhdf5ファイルを読み取るための直接的なアプローチです。

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
spate

HDF5には、 datasets (大まかに言うと「ファイル配列」に相当)を保存し、それらをグループに整理するための単純なオブジェクトモデルがあります(ディレクトリのようなものです)。これら2つのオブジェクトタイプの上に、理解の層を必要とするはるかに強力な機能があります。

手元にあるのは " Reference "です。これは、HDF5のストレージモデルの内部アドレスです。

h5pyは、可能な限りdictのようなインターフェイスに従うように努めているため、あいまいなルーチンを呼び出さずにすべての作業を行います(ただし、参照の場合、透過的にするのは少し複雑です)。

ドキュメントで探す場所は、 オブジェクトおよびリージョン参照 です。参照refが指すオブジェクトにアクセスするには、

 my_object = my_file[ref]

問題には、2つのステップがあります。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の場合、アイデアは保持されますが、簡単に書く方法は見当たりません。

参照を使用してデータをラウンドトリップする方法の完全なアイデアを得るために、短い「ライタープログラム」と短い「リーダープログラム」を作成しました。

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データ型で表現できないためです。それらは一度に1つずつ読み書きする必要があります。

3
Pierre de Buyl

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'])よりも高速です。唯一の欠点は、データプロバイダーが属性として割り当てることができるデータセットの形状を事前に知る必要があることです。

3
ArcherEX

以前に提案されたすべての回答を試しましたが、どれもうまくいきませんでした。たとえば、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]
1
Vinod Kumar

こんにちは、これはhdf5データを読み取るために使用する方法です。

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