Фильтрация набора данных HDF из файла H5 с использованием атрибута - PullRequest
0 голосов
/ 03 января 2019

У меня есть файл h5, содержащий несколько групп и наборов данных.Каждый набор данных имеет связанные атрибуты.Я хочу найти / отфильтровать наборы данных в этом файле h5 на основе соответствующего атрибута, связанного с ним.

Пример:

dataset1 =cloudy(attribute) 
dataset2 =rainy(attribute)
dataset3 =cloudy(attribute)

Я хочу найти наборы данныхс weather атрибутом / метаданными как cloudy

Какой будет самый простой способ сделать это pythonic способом.

Ответы [ 3 ]

0 голосов
/ 03 января 2019

Существует два способа доступа к данным HDF5 с помощью Python: h5py и pytables . Оба хороши, с разными возможностями:

  • h5py (из часто задаваемых вопросов по h5py): пытается отобразить для функции HDF5 значение NumPy как можно ближе. Некоторые говорят, что делает h5py более «питоническим».
  • PyTables (из FAQ по PyTables): создает дополнительный уровень абстракции поверх HDF5 и NumPy. Имеет более обширный поиск возможности (по сравнению с h5py).

При работе с данными HDF5 важно понимать модель данных HDF5. Это выходит за рамки этого поста. Для простоты представьте модель данных как файловую систему; где «группы» и «наборы данных» похожи на «папки» и «файлы». Оба могут иметь атрибуты. «узел» - это термин, используемый для обозначения «группы» или «набора данных».

@ Киран Рамачандра обрисовал метод с помощью h5py. Поскольку вы пометили свой пост pytables, описанный ниже тот же процесс с pytables.

Примечание. В примере Кирана предполагается, что наборы данных 1,2,3 находятся на корневом уровне. Вы сказали, что у вас также есть группы. Вероятно, у ваших групп также есть несколько наборов данных. Вы можете использовать утилиту HDFView для просмотра модели данных и ваших данных.

import tables as tb
h5f = tb.open_file('a.h5')

Это дает вам файловый объект, который вы используете для доступа к дополнительным объектам (группам или наборам данных).

h5f.walk_nodes() 

Это повторяемый объект для узлов и подузлов, который дает полную структуру данных HDF5 (помните, что "узлы" могут быть как группами, так и наборами данных). Вы можете перечислить все узлы и типы с помощью:

for anode in h5f.walk_nodes() :
    print (anode)

Используйте следующее для получения (нерекурсивного) списка имен узлов Python:

h5f.list_nodes() 

Будет извлечено значение атрибута cloudy из dataset1 (если оно существует):

h5f.root.dataset1._f_getattr('cloudy')

Если вам нужны все атрибуты для узла, используйте это (показано для dataset1):

ds1_attrs = h5f.root.dataset1._v_attrs._v_attrnames
for attr_name in ds1_attrs :
   print ('Attribute',  attr_name,'=' ,h5f.root.dataset1._f_getattr(attr_name))

Все вышеперечисленные ссылки dataset1 на корневом уровне (h5f.root). Если набор данных находится в группе, вы просто добавляете имя группы в путь. Для dataset2 в группе с именем agroup используйте:

h5f.root.agroup.dataset2._f_getattr('rainy')

Будет извлечено значение атрибута rainy из dataset2 в agroup (если оно существует)

Если вы хотите, чтобы все атрибуты для dataset2:

ds2_attrs = h5f.root.agroup.dataset2._v_attrs._v_attrnames
for attr_name in ds2_attrs :
   print ('Attribute',  attr_name,'=' , h5f.root.agroup.dataset2._f_getattr(attr_name))

Для полноты прилагается ниже код для создания a.h5, используемый в моем примере. numpy требуется только для определения dtype при создании таблицы. Как правило, файлы HDF5 являются взаимозаменяемыми (поэтому вы можете открыть этот пример с помощью h5py).

import tables as tb
import numpy as np
h5f = tb.open_file('a.h5','w')

#create dataset 1 at root level, and assign attribute
ds_dtype = np.dtype([('a',int),('b',float)])
dataset1 = h5f.create_table(h5f.root, 'dataset1', description=ds_dtype)
dataset1._f_setattr('cloudy', 'True')

#create a group at root level
h5f.create_group(h5f.root, 'agroup')

#create dataset 2,3 at root.agroup level, and assign attributes
dataset2 = h5f.create_table(h5f.root.agroup, 'dataset2', description=ds_dtype)
dataset2._f_setattr('rainy', 'True')
dataset3 = h5f.create_table(h5f.root.agroup, 'dataset3', description=ds_dtype)
dataset3._f_setattr('cloudy', 'True')

h5f.close()
0 голосов
/ 04 января 2019

Это модификация кода Сумита (размещена в его ответе). Примечание. Я удалил оператор f.close() после вызовов create_group и create_dataset. После добавления атрибутов последний раздел кода извлекает их (и печатает имя / значение атрибута в именах групп / наборов данных).

import h5py

dat=[1,2,3,45]

with h5py.File('temp.h5', 'w') as f:
    group1 = f.create_group('my_group1')
    dset11 = group1.create_dataset('my_dataset11', data=dat, compression=9)
    dset12 = group1.create_dataset('my_dataset12', data=dat, compression=9)
    dset13 = group1.create_dataset('my_dataset13', data=dat, compression=9)
    group2 = f.create_group('my_group2')
    dset21 = group2.create_dataset('my_dataset21', data=dat, compression=9)
    dset22 = group2.create_dataset('my_dataset22', data=dat, compression=9)
    dset23 = group2.create_dataset('my_dataset23', data=dat, compression=9)

    groups=list(f.keys())

    grp=f[groups[0]]
    dataset=list(grp.keys())

    for each in dataset:
        grp[each].attrs['env']='cloudy'
        grp[each].attrs['temp']=25
#        grp[each]._f_setattr('cloudy', 'True')

    grp=f[groups[1]]
    dataset=list(grp.keys())

    for each in dataset:
        grp[each].attrs['env']='rainy'
        grp[each].attrs['temp']=20
#        grp[each]._f_setattr('rainy', 'True')

    for each_grp in groups:
        dataset=list(f[each_grp].keys())
        for each_ds in dataset:
            print ('For ', each_grp, '.', each_ds,':')
            print ('\tenv =', f[each_grp][each_ds].attrs['env'])
            print ('\ttemp=',f[each_grp][each_ds].attrs['temp'])

f.close()

Вывод должен выглядеть так:

For  my_group1 . my_dataset11 :
    env = cloudy
    temp= 25
For  my_group1 . my_dataset12 :
    env = cloudy
    temp= 25
For  my_group1 . my_dataset13 :
    env = cloudy
    temp= 25
For  my_group2 . my_dataset21 :
    env = rainy
    temp= 20
For  my_group2 . my_dataset22 :
    env = rainy
    temp= 20
For  my_group2 . my_dataset23 :
    env = rainy
    temp= 20
0 голосов
/ 03 января 2019

Вы можете напрямую получить наборы данных из файла h5 следующим образом.Допустим, у вас есть файл .h5, который вы можете использовать для фильтрации содержимого следующим образом:

import h5py
import numpy
data = h5py.File('a.h5', 'r')

Теперь данные - это объект, который можно использовать в качестве словаря.Если вам нужны атрибуты, то

data.keys()

Это приведет к извлечению всех атрибутов данных в файлах h5. В вашем случае набор данных1, набор данных2, набор данных3

Снова отдельные наборы данных представлены в видеопять словарь.Так,

data.['dataset1'].keys()

Это принесет облачность, и так далее, если существует

data.['dataset2'].keys()

Это принесет дождю, и так далее, если существует

data.['dataset3'].keys()

Этобудет извлекать облачность и т. д., если существует

Если вы хотите использовать эти данные, просто попробуйте получить к ним доступ как диктовку

data.['dataset1']['cloudy']
data.['dataset2']['rainy']
data.['dataset3']['cloudy']

Как только вы узнаете ключи, вы можете искать нужные ключипросто с помощью метода has_key ()

if data.['dataset3'].has_key('cloudy') == 1:

Затем добавьте данные в требуемую переменную.Проще всего конвертировать их в массивы numpy.

...