【问题标题】:How to differentiate between HDF5 datasets and groups with h5py?如何区分 HDF5 数据集和使用 h5py 的组?
【发布时间】:2016-03-23 16:00:51
【问题描述】:

我使用 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() 来区分数据集和组之外,没有明显的方法。不幸的是,h5py documentation 没有提及这个话题。他们总是假设您事先知道什么是组和什么是数据集,例如因为他们自己创建了数据集。

我想要类似的东西:

f = h5py.File(..)
for key in f.keys():
    x = f[key]
    print(x.is_group(), x.is_dataset()) # does not exist

使用 h5py 在 Python 中读取未知 hdf5 文件时,如何区分组和数据集?如何获取所有数据集、所有组、所有链接的列表?

【问题讨论】:

    标签: python hdf5 h5py


    【解决方案1】:

    不幸的是,h5py api 中没有内置的方法来检查这个,但你可以简单地用is_dataset = isinstance(item, h5py.Dataset) 来检查项目的类型。

    要列出文件的所有内容(但文件的属性除外),您可以将 Group.visititems 与一个可调用项一起使用,该可调用项获取项目的名称和实例。

    【讨论】:

    • 谢谢。我猜所有组都来自h5py.Group,所有软链接来自h5py.SoftLink,所有硬链接来自h5py.HardLink
    • 呵呵,我忘了提一个例外。如果我没记错的话,visititems 不会访问外部链接。
    【解决方案2】:

    因为 h5py 使用 python 字典作为交互的首选方法,所以您需要使用“values()”函数来实际访问项目。所以你也许可以使用列表过滤器:

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

    以递归方式执行此操作应该很简单。

    【讨论】:

      【解决方案3】:

      虽然 Gall 和 James Smith 的回答总体上表明了解决方案,但仍然需要完成对分层 HDF 结构的遍历和所有数据集的过滤。我使用yield from 完成了它,它在 Python 3.3+ 中可用,它工作得非常好,并在这里展示它。

      import h5py
      
      def h5py_dataset_iterator(g, prefix=''):
          for key, item in g.items():
              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)
      

      【讨论】:

        【解决方案4】:

        我更喜欢这个解决方案。它在 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) ]
        

        【讨论】:

          【解决方案5】:

          例如,如果要打印HDF5 文件的结构,可以使用以下代码:

          def h5printR(item, leading = ''):
              for key in item:
                  if isinstance(item[key], h5py.Dataset):
                      print(leading + key + ': ' + str(item[key].shape))
                  else:
                      print(leading + key)
                      h5printR(item[key], leading + '  ')
          
          # Print structure of a `.h5` file            
          def h5print(filename):
              with h5py.File(filename, 'r') as h:
                  print(filename)
                  h5printR(h, '  ')
          

          示例

          >>> h5print('/path/to/file.h5')
          
          file.h5
            test
              repeats
                cell01: (2, 300)
                cell02: (2, 300)
                cell03: (2, 300)
                cell04: (2, 300)
                cell05: (2, 300)
              response
                firing_rate_10ms: (28, 30011)
              stimulus: (300, 50, 50)
              time: (300,)
          

          【讨论】:

            猜你喜欢
            • 2021-08-01
            • 2015-10-29
            • 2015-04-17
            • 2016-04-04
            • 2016-02-27
            • 2021-09-24
            • 2017-03-15
            • 2016-06-05
            • 2020-10-27
            相关资源
            最近更新 更多