Как различать наборы данных 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()
чтобы различать наборы данных и групп. The h5py документация к сожалению ничего не говорит об этой теме. Они всегда предполагают, что вы заранее знаете, что такое группы и что такое наборы данных, например, потому что они сами создали наборы данных.
Я хотел бы иметь что-то вроде:
f = h5py.File(..)
for key in f.keys():
x = f[key]
print(x.is_group(), x.is_dataset()) # does not exist
как я могу различать группы и наборы данных при чтении неизвестного файла hdf5 в Python с помощью h5py? Как я могу получить список всех наборов данных, всех групп, всех ссылок?
4 ответов
к сожалению, в api h5py нет встроенного способа проверить это, но вы можете просто проверить тип элемента с помощью is_dataset = isinstance(item, h5py.Dataset)
.
чтобы перечислить все содержимое файла (за исключением атрибутов файла), вы можете использовать Group.visititems
с вызываемым, который принимает имя и экземпляр элемента.
в то время как ответы Галла и Джеймса Смита указывают на решение в целом, обход через иерархическую структуру 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)
поскольку h5py использует словари python в качестве метода выбора для взаимодействия, вам нужно использовать функцию "values()" для фактического доступа к элементам. Таким образом, вы можете использовать фильтры списка:
datasets = [item for item in f["Data"].values() if isinstance(item, h5py.Dataset)]
выполнение этого рекурсивно должно быть достаточно простым.
Я предпочитаю это решение. Он находит список всех объектов в файле 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) ]