我使用pytables创建了从一个hdf5文件指向另一个文件的外部链接。我的问题是如何在循环中取消引用它?
例如:
假设file_name = "collection.h5"
,其中存储了外部链接
我在根节点下创建了外部链接,当我遍历根节点下的节点时,得到以下输出:
/ link1(ExternalLink)-> /files/data1.h5:/weights/Image
/ link2(ExternalLink)-> /files/data2.h5:/weights/Image
以此类推,
我知道,要取消对链接的引用,可以按照以下方式使用自然命名来完成此操作:
f = open_file('collection.h5',mode='r')
plink1 = f.root.link1()
plink2 = f.root.link2()
但是我想在for循环中执行此操作,对此有任何帮助吗?
答案 0 :(得分:0)
您可以使用iter_nodes()
或walk_nodes()
; walk_nodes
是递归的,iter_nodes
不是递归的。我对这个SO主题的回答说明了iter_nodes()
的一个示例:
cannot-retrieve-datasets-in-pytables-using-natural-naming
我发现您不能使用get_node()
来引用ExternalLink。您需要使用不同的引用。
这是一个简单的示例,该示例从本地文件夹中的HDF5文件列表创建collection.h5
,然后在iter_nodes()
循环中使用for
。请注意,这是一个非常基本的示例。它不会检查节点的对象类型(组或叶或外部链接)。假定根级别的每个 Node 都是 ExternalLink ,并从该节点创建文件对象。还有其他PyTables方法和属性可检查这些情况。有关更健壮(复杂)的方法,请参见下面的详细答案。
import tables as tb
import glob
h5f = tb.open_file('collection.h5',mode='w')
link_cnt = 0
for h5name in glob.glob('./SO*.h5'):
link_cnt += 1
h5f.create_external_link('/', 'link'+str(link_cnt), h5name+':/')
h5f.close()
h5f = tb.open_file('collection.h5',mode='r')
for link_node in h5f.iter_nodes('/') :
print("``%s`` is an external link to: ``%s``" % (link_node, link_node.target))
plink = link_node(mode='r') # returns a FILE object
h5f.close()
答案 1 :(得分:0)
当您在任何组级别具有一个ExternalLink时,这是一个更完整(鲁棒且复杂)的答案,可以处理一般情况。它与上面类似,但是使用walk_nodes()
,因为它在根级别具有3个组,并包含一个针对ExternalLink类型的测试(请参见isinstance()
)。此外,它还显示了如何使用_v_children
属性来获取节点字典。 (我无法让list_nodes()
使用ExternalLink。)
import tables as tb
import glob
h5f = tb.open_file('collection.h5',mode='w')
link_cnt = 0
pre_list = ['SO_53', 'SO_54', 'SO_55']
for h5f_pre in pre_list :
h5f_pre_grp = h5f.create_group('/', h5f_pre)
for h5name in glob.glob('./'+h5f_pre+'*.h5'):
link_cnt += 1
h5f.create_external_link(h5f_pre_grp, 'link_'+'%02d'%(link_cnt), h5name+':/')
h5f.close()
h5f = tb.open_file('collection.h5',mode='r')
for link_node in h5f.walk_nodes('/') :
if isinstance(link_node, tb.link.ExternalLink) :
print('\nFor Node %s:' % (link_node._v_pathname) )
print("``%s`` is an external link to: ``%s``" % (link_node, link_node.target))
plink = link_node(mode='r') # this returns a file object for the linked file
linked_nodes = plink._v_children
print (linked_nodes)
h5f.close()