web-dev-qa-db-ja.com

HDF5データセットとh5pyのグループを区別する方法は?

Pythonパッケージh5py(バージョン2.5.0)を使用して、hdf5ファイルにアクセスします。

ファイルの内容を走査して、すべてのデータセットで何かをしたいと思っています。

visitメソッドの使用:

_import h5py

def print_it(name):
    dset = f[name]
    print(dset)
    print(type(dset))


with h5py.File('test.hdf5', 'r') as f:
    f.visit(print_it)
_

私が入手したテストファイルの場合:

_<HDF5 group "/x" (1 members)>
<class 'h5py._hl.group.Group'>
<HDF5 dataset "y": shape (100, 100, 100), type "<f8">
<class 'h5py._hl.dataset.Dataset'>
_

これにより、ファイルにデータセットとグループがあることがわかります。ただし、type()を使用してデータセットとグループを区別する以外に明確な方法はありません。 h5py documentation 残念ながら、このトピックについては何も述べられていません。たとえば、データセット自体を作成したため、グループとデータセットを事前に知っていると常に想定しています。

私は次のようなものが欲しいです:

_f = h5py.File(..)
for key in f.keys():
    x = f[key]
    print(x.is_group(), x.is_dataset()) # does not exist
_

Python with h5py)で不明なhdf5ファイルを読み取るときに、グループとデータセットを区別するにはどうすればよいですか?すべてのデータセット、すべてのグループ、すべてのリンクのリストを取得するにはどうすればよいですか?

15
Trilarion

残念ながら、これをチェックするための組み込みの方法はh5py APIにはありませんが、is_dataset = isinstance(item, h5py.Dataset)を使用して項目のタイプを簡単にチェックできます。

ファイルのすべてのコンテンツを一覧表示するには(ただし、ファイルの属性を除く) Group.visititems は、アイテムの名前とインスタンスを取得する呼び出し可能オブジェクトを使用します。

13
Gall

GallとJames Smithの回答は一般的な解決策を示していますが、階層的なHDF構造のトラバーサルとすべてのデータセットのフィルタリングを実行する必要があります。 yield fromはPython 3.3+で利用できます)これは非常にうまく機能し、ここに表示されます。

import h5py

def h5py_dataset_iterator(g, prefix=''):
    for key in g.keys():
        item = g[key]
        path = '{}/{}'.format(prefix, key)
        if isinstance(item, h5py.Dataset): # test for dataset
            yield (path, item)
        Elif isinstance(item, h5py.Group): # test for group (go down)
            yield from h5py_dataset_iterator(item, path)

with h5py.File('test.hdf5', 'r') as f:
    for (path, dset) in h5py_dataset_iterator(f):
        print(path, dset)
5
Trilarion

H5pyは対話の選択方法としてpython辞書を使用するため、 "values()"関数を使用して実際にアイテムにアクセスする必要があります。したがって、リストフィルターを使用できる場合があります:

datasets = [item for item in f["Data"].values() if isinstance(item, h5py.Dataset)]

これを再帰的に行うことは十分簡単なはずです。

1
James Smith

私はこの解決策を好みます。これは、hdf5ファイル "h5file"内のすべてのオブジェクトのリストを検索し、クラスに基づいてそれらをソートします。これは、前述の方法と同様ですが、そのような簡潔な方法ではありません。

import h5py
fh5 = h5py.File(h5file,'r')
fh5.visit(all_h5_objs.append)
all_groups   = [ obj for obj in all_h5_objs if isinstance(fh5[obj],h5py.Group) ]
all_datasets = [ obj for obj in all_h5_objs if isinstance(fh5[obj],h5py.Dataset) ]
0
Scott N

たとえば、HDF5ファイルの構造を印刷する場合は、次のコードを使用できます。

def h5printR(item, leading = ''):
    for key in item:
        if isinstance(item[key], h5py.Dataset):
            print(leading + key + ': ' + str(item[key].shape))
        else:
            print(leading + key)
            h5printR(item[key], leading + '  ')

# Print structure of a `.h5` file            
def h5print(filename):
    with h5py.File(filename, 'r') as h:
        print(filename)
        h5printR(h, '  ')

>>> h5print('/path/to/file.h5')

file.h5
  test
    repeats
      cell01: (2, 300)
      cell02: (2, 300)
      cell03: (2, 300)
      cell04: (2, 300)
      cell05: (2, 300)
    response
      firing_rate_10ms: (28, 30011)
    stimulus: (300, 50, 50)
    time: (300,)
0
Yas