【问题标题】:Filter HDF dataset from H5 file using attribute使用属性从 H5 文件中过滤 HDF 数据集
【发布时间】:2019-05-29 21:56:04
【问题描述】:

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

示例:

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

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

pythonic 方式完成此任务的最简单方法是什么。

【问题讨论】:

  • 下面的答案是一个很好的起点。从这里您应该查看 pytables 和 h5py 文档。我都使用过,它们都写得很好并且非常有用(有方法和属性的教程和参考)。这里的 Pytables:pytables.org/usersguide/index.html 和这里的 h5py:docs.h5py.org/en/stable

标签: python hdf5 h5py pytables hdfql


【解决方案1】:

有两种使用 Python 访问 HDF5 数据的方法:h5pypytables。 两者都很好,具有不同的功能:

  • h5py(来自 h5py FAQ):尝试将 HDF5 功能集映射到 NumPy 尽可能接近。有人说这让 h5py 更加“pythonic”。
  • PyTables(来自 PyTables FAQ):在 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() 

这将从dataset1 获取属性cloudy 的值(如果存在):

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)。 如果数据集在一个组中,您只需将组名添加到路径中。 对于名为 agroup 的组中的 dataset2,请使用:

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

这将从agroup 中的dataset2 获取属性rainy 的值(如果存在)

如果你想要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()

【讨论】:

  • 谢谢,但请您帮助以下查询
【解决方案2】:

您可以通过以下方式直接从 h5file 中获取数据集。 假设您有一个 .h5 文件,您可以使用它以以下 Python 方式过滤掉内容。

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()

这将获取多云,如果存在则依此类推

如果您想使用该数据,那么只需尝试将其作为 dict 访问

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

一旦你知道了密钥,你就可以使用 has_key() 方法搜索所需的密钥

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

然后将数据附加到所需的变量上。 最简单的方法是将它们转换为 numpy 数组。

【讨论】:

    【解决方案3】:

    这是对 Sumit 代码的修改(发布在他的回答中)。 注意:我在create_groupcreate_dataset 调用之后删除了f.close() 语句。添加属性后,最后一段代码检索它们(并在组/数据集名称下打印属性名称/值)。

    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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-11-18
      • 2014-08-05
      • 2019-10-04
      • 1970-01-01
      • 2016-06-08
      • 2020-09-15
      相关资源
      最近更新 更多