使用h5py合并所有h5文件

时间:2018-04-16 06:45:04

标签: python h5py

我是编码的新手。有人可以使用h5py帮助Python中的脚本,其中我们可以读取所有目录和子目录,将多个h5文件合并为一个h5文件。

1 个答案:

答案 0 :(得分:1)

您需要的是文件中所有数据集的列表。我认为recursive function的概念就是这里所需要的。这将允许您从组中提取所有“数据集”,但当其中一个看起来是一个组本身时,递归执行相同的操作,直到找到所有数据集。例如:

/
|- dataset1
|- group1
   |- dataset2
   |- dataset3
|- dataset4

你的函数应该在伪代码中看起来像:

def getdatasets(key, file):

  out = []

  for name in file[key]:

    path = join(key, name)

    if file[path] is dataset: out += [path]
    else                      out += getdatasets(path, file)

  return out

对于我们的例子:

  1. /dataset1是一个数据集:添加输出路径,给出

    out = ['/dataset1']
    
  2. /group不是数据集:call getdatasets('/group',file)

    1. /group/dataset2是一个数据集:添加输出路径,给出

      nested_out = ['/group/dataset2']
      
    2. /group/dataset3是一个数据集:添加输出路径,给出

      nested_out = ['/group/dataset2', '/group/dataset3']
      
    3. 这已添加到我们已有的内容中:

      out = ['/dataset1', '/group/dataset2', '/group/dataset3']
      
    4. /dataset4是一个数据集:添加输出路径,给出

      out = ['/dataset1', '/group/dataset2', '/group/dataset3', '/dataset4']
      
    5. 此列表可用于将所有数据复制到另一个文件。

      要制作一个简单的克隆,您可以执行以下操作。

      import h5py
      import numpy as np
      
      # function to return a list of paths to each dataset
      def getdatasets(key,archive):
      
        if key[-1] != '/': key += '/'
      
        out = []
      
        for name in archive[key]:
      
          path = key + name
      
          if isinstance(archive[path], h5py.Dataset):
            out += [path]
          else:
             out += getdatasets(path,archive)
      
        return out
      
      
      # open HDF5-files
      data     = h5py.File('old.hdf5','r')
      new_data = h5py.File('new.hdf5','w')
      
      # read as much datasets as possible from the old HDF5-file
      datasets = getdatasets('/',data)
      
      # get the group-names from the lists of datasets
      groups = list(set([i[::-1].split('/',1)[1][::-1] for i in datasets]))
      groups = [i for i in groups if len(i)>0]
      
      # sort groups based on depth
      idx    = np.argsort(np.array([len(i.split('/')) for i in groups]))
      groups = [groups[i] for i in idx]
      
      # create all groups that contain dataset that will be copied
      for group in groups:
        new_data.create_group(group)
      
      # copy datasets
      for path in datasets:
      
        # - get group name
        group = path[::-1].split('/',1)[1][::-1]
      
        # - minimum group name
        if len(group) == 0: group = '/'
      
        # - copy data
        data.copy(path, new_data[group])
      

      当然,根据您的需要,可以进行进一步的自定义。您描述了一些文件组合。在这种情况下,你必须

       new_data = h5py.File('new.hdf5','a')
      

      并且可能会在路径上添加一些内容。