Python 组合hdf5文件

Python 组合hdf5文件,python,hdf5,h5py,Python,Hdf5,H5py,我有许多hdf5文件,每个文件都有一个数据集。数据集太大,无法保存在RAM中。我想将这些文件合并成一个单独包含所有数据集的文件(即而不是将数据集连接成一个数据集) 一种方法是创建一个hdf5文件,然后逐个复制数据集。这将是缓慢而复杂的,因为它将需要缓冲副本 有没有更简单的方法?看起来应该有,因为它本质上只是创建一个容器文件 我正在使用python/h5py。我通过使用官方hdf5工具找到了一个非python解决方案。h5copy可以将单个指定数据集从hdf5文件复制到另一个现有hdf5文件中 如

我有许多hdf5文件,每个文件都有一个数据集。数据集太大,无法保存在RAM中。我想将这些文件合并成一个单独包含所有数据集的文件(即而不是将数据集连接成一个数据集)

一种方法是创建一个hdf5文件,然后逐个复制数据集。这将是缓慢而复杂的,因为它将需要缓冲副本

有没有更简单的方法?看起来应该有,因为它本质上只是创建一个容器文件


我正在使用python/h5py。

我通过使用官方hdf5工具找到了一个非python解决方案。h5copy可以将单个指定数据集从hdf5文件复制到另一个现有hdf5文件中


如果有人找到一个基于python/h5py的解决方案,我会很高兴听到这个消息。

这实际上是HDF5的一个用例。 如果您只想从一个文件中访问所有数据集,而不关心它们在磁盘上的实际存储方式,那么可以使用。从:

外部链接允许组在另一个HDF5文件中包含对象,并使库能够像在当前文件中一样访问这些对象。以这种方式,组可能看起来直接包含数据集、命名数据类型,甚至包含实际位于不同文件中的组。此功能通过一套功能实现,这些功能可创建和管理链接、定义和检索指向外部对象的路径以及解释链接名称:

:

小心:打开
myfile
时,如果它是现有文件,则应使用
'a'
打开它。如果您用
'w'
打开它,它将删除其内容


这比将所有数据集复制到新文件中要快得多。我不知道访问
otherfile.hdf5
的速度有多快,但对所有数据集的操作都是透明的——也就是说,h5py将看到所有数据集都驻留在
foo.hdf5

一个解决方案是将
h5py
接口用于hdf5api的低级
H5Ocopy
,尤其是
h5py.h5o.copy

[1]中的
:将h5py作为h5导入
[2]中:hf1=h5.File(“f1.h5”)
在[3]中:hf2=h5.File(“f2.h5”)
[4]中:hf1.创建_数据集(“val”,data=35)
出[4]:
[5]中:hf1.创建_组(“g1”)
出[5]:
在[6]中:hf1.get(“g1”).create_数据集(“val2”,data=“Thing”)
出[6]:
在[7]:hf1.flush()中
[8]中:h5.h5o.副本(hf1.id,“g1”,hf2.id,“newg1”)
在[9]中:h5.h5o.副本(hf1.id,“val”,hf2.id,“newval”)
[10]:hf2.values()
Out[10]:[,]
在[11]中:hf2.get(“newval”).value
Out[11]:35
[12]中:hf2.get(“newg1”).values()
输出[12]:[]
在[13]中:hf2.get(“newg1”).get(“val2”).value
Out[13]:“东西”
上面的代码是由Python版本
2.7.3-4+deb7u1
上的
h5py
版本
2.0.1-2+b1
和iPython版本
0.13.1-2+deb7u1
生成的,这两个版本或多或少都是由Debian Wheezy的普通安装程序生成的。执行上述操作之前,文件
f1.h5
f2.h5
不存在请注意,根据,对于Python 3,数据集/组名称需要是
字节
(例如,
),而不是

命令
[7]
中的
hf1.flush()
非常重要,因为低级接口显然总是从存储在磁盘上的
.h5
文件版本中提取,而不是从缓存在内存中的文件。通过使用
hf1.get(“g1”).ID
等提供该组的ID,可以实现向不在
文件根目录下的组复制数据集或从该组复制数据集

请注意,
h5py.h5o.copy
如果目标位置中已存在指定名称的对象,则会出现异常(无阻塞)而失败。

我通常将和工具一起使用,这比纯python解决方案快得多。一旦安装,请复制

控制台解决方案M.W.E。 自动控制台解决方案 若要完全自动化此过程(假设您正在存储要合并的文件的文件夹中工作),请执行以下操作:

import os 
d_names = os.listdir(os.getcwd())
d_struct = {} #Here we will store the database structure
for i in d_names:
   f = h5py.File(i,'r+')
   d_struct[i] = f.keys()
   f.close()

# A) empty all the groups in the new .h5 file 
for i in d_names:
    for j  in d_struct[i]:
        !h5copy -i '{i}' -o 'output.h5' -s {j} -d {j}
为添加的每个.h5文件创建一个新组 如果要在output.h5中保持前一个数据集的独立性,必须首先使用标志
-p

 # B) Create a new group in the output.h5 file for every input.h5 file
 for i in d_names:
        dataset = d_struct[i][0]
        newgroup = '%s/%s' %(i[:-3],dataset)
        !h5copy -i '{i}' -o 'output.h5' -s {dataset} -d {newgroup} -p
        for j  in d_struct[i][1:]:
            newgroup = '%s/%s' %(i[:-3],j) 
            !h5copy -i '{i}' -o 'output.h5' -s {j} -d {newgroup}

为了对此进行更新,HDF5 1.10版附带了一个新功能,该功能在这种情况下可能非常有用,称为“虚拟数据集”。
这里有一个简短的教程和一些解释: .
下面是有关该功能的更完整、更详细的说明和文档:
.
在这里,h5py中合并的pull请求将虚拟datatsetsapi包含到h5py中:
但是我不知道它是否已经在当前的h5py版本中提供,或者稍后会提供。

要使用Python(而不是IPython)和h5copy合并HDF5文件,我们可以基于:


看起来这个问题已经得到了回答:@MattPavelle据我所知,这与我想要的不同。我不想将数据集连接到单个数据集中,而是将它们作为单独的数据集保存在一个文件中。明白了,感谢您的澄清和编辑。请原谅我的后续行动——我玩HDF5已经有几年了——但我认为h5merge不会起作用吗?@MattPavelle现在看着它,不确定。h5merge似乎不是官方hdf5工具的一部分,它的文档似乎有点糟糕。我一直在寻找python/h5py解决方案,但我还将进一步探索可用的hdf5 unix工具。谢谢。是的,这不是一个官方的hdf5工具-而且它肯定不是Pythonic:)但它可能是你最好的选择。谢谢,这是一个很好的技巧。不过,在我的例子中,我更喜欢将它们真正包含在一个文件中。但是,如果复制速度太慢,我可能会使用此方法。应该选择此方法作为问题的答案。如果要执行此操作并且有很多链接,请确保使用H5Pset_libver_边界(
#PLESE NOTE THIS IS IPYTHON CONSOLE CODE NOT PURE PYTHON

import h5py
#for every dataset Dn.h5 you want to merge to Output.h5 
f = h5py.File('D1.h5','r+') #file to be merged 
h5_keys = f.keys() #get the keys (You can remove the keys you don't use)
f.close() #close the file
for i in h5_keys:
        !h5copy -i 'D1.h5' -o 'Output.h5' -s {i} -d {i}
import os 
d_names = os.listdir(os.getcwd())
d_struct = {} #Here we will store the database structure
for i in d_names:
   f = h5py.File(i,'r+')
   d_struct[i] = f.keys()
   f.close()

# A) empty all the groups in the new .h5 file 
for i in d_names:
    for j  in d_struct[i]:
        !h5copy -i '{i}' -o 'output.h5' -s {j} -d {j}
 # B) Create a new group in the output.h5 file for every input.h5 file
 for i in d_names:
        dataset = d_struct[i][0]
        newgroup = '%s/%s' %(i[:-3],dataset)
        !h5copy -i '{i}' -o 'output.h5' -s {dataset} -d {newgroup} -p
        for j  in d_struct[i][1:]:
            newgroup = '%s/%s' %(i[:-3],j) 
            !h5copy -i '{i}' -o 'output.h5' -s {j} -d {newgroup}
import h5py
import os

d_names = os.listdir(os.getcwd())
d_struct = {} #Here we will store the database structure
for i in d_names:
   f = h5py.File(i,'r+')
   d_struct[i] = f.keys()
   f.close()

for i in d_names:
   for j  in d_struct[i]:
      os.system('h5copy -i %s -o output.h5 -s %s -d %s' % (i, j, j))