2015-12-17 4 views
7

Я использую пакет Python h5py (версия 2.5.0) для доступа к моим файлам hdf5.Как отличить набор данных HDF5 от групп с h5py?

Я хочу пройти содержимое файла и сделать что-то с каждым набором данных.

Используя 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 

Как я могу различать между группами и наборами данных при чтении неизвестный файл hdf5 в Python с h5py? Как я могу получить список всех наборов данных, всех групп, всех ссылок?

ответ

6

К сожалению, в h5py api нет встроенного способа проверки, но вы можете просто проверить тип элемента с помощью is_dataset = isinstance(item, h5py.Dataset).

Чтобы отобразить все содержимое файла (кроме атрибутов файла), вы можете использовать Group.visititems с вызываемым, который принимает имя и экземпляр элемента.

+0

Спасибо. Я думаю, что все группы происходят из 'h5py.Group', всех софт-ссылок из' h5py.SoftLink' и всех жестких ссылок из 'h5py.HardLink'. – Trilarion

+0

Хо, за одним исключением я забыл упомянуть. Если я правильно помню, '' visititems'' не посещает внешние ссылки. – Gall

1

Поскольку h5py использует словари python как свой метод выбора для взаимодействия, вам нужно использовать функцию «values ​​()» для фактического доступа к элементам. Таким образом, вы можете использовать список фильтров:

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

Выполнение этого рекурсивно должно быть достаточно простым.

3

Хотя ответы Галла и Джеймса Смита указывают на решение в целом, обход через иерархическую структуру 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) 
0

Я предпочитаю это решение. Он находит список всех объектов в файл «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) ] 
Смежные вопросы