使用属性从H5文件过滤HDF数据集

时间:2019-01-03 10:08:48

标签: python hdf5 h5py pytables hdfql

我有一个h5文件,其中包含多个组和数据集。每个数据集都有关联的属性。我想根据与之关联的各个属性在此h5文件中查找/过滤数据集。

示例:

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

我想找到具有weather属性/元数据为cloudy的数据集

pythonic 方式完成此操作的最简单方法是什么。

3 个答案:

答案 0 :(得分:1)

有两种使用Python访问HDF5数据的方式: h5py pytables 。 两者都很好,但功能不同:

  • h5py (来自h5py常见问题解答):尝试将HDF5功能集映射到NumPy 尽可能紧密。有人说这使h5py更具“ pythonic”性。
  • PyTables (来自PyTables常见问题解答):在HDF5和NumPy之上构建一个附加的抽象层。搜索范围更广 功能(与h5py相比)。

使用HDF5数据时,了解HDF5数据模型很重要。那超出了这篇文章的范围。为了简单起见,请将数据模型视为文件系统;其中“组”和“数据集”就像“文件夹”和“文件”。两者都可以具有属性。 “节点”是用于指代“组”或“数据集”的术语。

@Kiran Ramachandra用h5py概述了一种方法。由于您使用pytables标记了帖子,因此以下概述的使用pytables的过程是相同的。

注意:Kiran的示例假定数据集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()

答案 1 :(得分:0)

您可以按照以下方式直接从h5文件中获取数据集。 假设您有一个.h5文件,您可以使用该文件以下面的pythonic方式过滤掉内容。

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

现在数据是可以用作字典的对象。 如果您想要属性,那么

data.keys()

这将获取h5文件中的所有数据属性。在您的情况下,dataset1,dataset2,dataset3

再次将单个数据集重新以字典的形式。所以,

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数组。

答案 2 :(得分:0)

这是Sumit代码的修改(张贴在他的答案中)。 注意:我在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