Как отменить ссылку на список внешних ссылок, используя pytables? - PullRequest
0 голосов
/ 28 марта 2019

Я создал внешние ссылки, ведущие из одного файла hdf5 в другой, используя pytables. Мой вопрос, как отменить ссылку в цикле?

например:

Предположим 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, любая помощь по этому поводу?

Ответы [ 2 ]

0 голосов
/ 28 марта 2019

Это более полный (надежный и сложный) ответ для обработки общего условия, когда у вас есть 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()
0 голосов
/ 28 марта 2019

Вы можете использовать iter_nodes() или walk_nodes(); walk_nodes является рекурсивным, iter_nodes - нет. Пример iter_nodes() объясняется в моем ответе на эту тему SO: не-извлечения-наборов данных в-pytables-с использованием натуральных-именование Я обнаружил, что вы не можете использовать get_node() для ссылки на ExternalLink. Вам нужно ссылаться по-другому.

Вот простой пример, который создает collection.h5 из списка файлов HDF5 в моей локальной папке, а затем использует iter_nodes() в цикле for. Обратите внимание, что это очень простой пример. Он не проверяет тип объекта узла ( Группа или Leaf или ExternalLink ). Предполагается, что каждый Узел на корневом уровне является 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()
...