2015-12-03 2 views
2

Я использую библиотеку NetworkX с Python.Доступ к узлу строковой метки с внутренней частью строки

Я хочу иметь возможность обращаться к узлу, используя только идентификатор int, который является частью имени узла (строки) для различных целей, например, для получения кратчайшего пути между двумя узлами.

MWE:

Допустим, что я импортировать Pajek отформатированный файл:

import networkx as nx 
G=nx.read_pajek("pajek_network_file.net") 
G=nx.Graph(G) 

Содержимое моего файла являются (В Pajek, узлы называются "Вершины"):

*Network 
*Vertices 6 
123 Author1 
456 Author2 
789 Author3 
111 Author4 
222 Author5 
333 Author6 
*Edges 
123 333 
333 789 
789 222 

Какую команду следует использовать для печати узла Author4, используя только его идентификатор 111?

До сих пор я пытался формат G.node [NodeId], как:

print G.node[111] 

, но это возвращает ошибку, потому что он пытается найти узел LABEL = 111, что, конечно, не существует.

В последующий вопрос, в идеале я хотел бы не только напечатать узел по идентификатору, но и использовать ее с функциями, такие как

nx.shortest_path_length(G,source_nodeid,target_nodeid) 

Что я делаю как произведение вокруг на данный момент создается сетевой файл .net с повторением столбца идентификатора узла дважды, чтобы использовать тот же номер идентификатора, что и «метка узла».

Я уверен, что ответ должен быть очень простым, но он просто ускользнул от меня до тех пор, даже после многократного Googling и прохождения документации ... Любая помощь будет оценена!

ответ

0

Я считаю, что вы ищете функцию nx.relabel_nodes, которая принимает словарь для сопоставления старых ярлыков с новыми ярлыками. Я использовал имена вершин, которые вы предоставили для построения графика. Затем создайте словарь, который сопоставляет старые метки (полную строку) с новыми ярлыками (целочисленный листинг первого элемента строки после его разбиения). Наконец, я использовал функцию relabel_nodes, чтобы выполнить повторное использование.

Вот как я использовал его, чтобы решить вашу проблему:

G = nx.Graph() 
vertices = ['123 Author1','456 Author2','789 Author3','111 Author4','222 Author5','333 Author6'] 
for v in vertices: 
    G.add_node(v) 
# Maps old labels to new labels 
new_labels = dict((i , int(i.split()[0])) for i in G.nodes()) 
print new_labels 
# Relabel nodes 
nx.relabel_nodes(G,new_labels,False) 
# To access node with integer 123 for instance 
print G[123] 
# Draw the network with all labels 
nx.draw_networkx(G, with_labels=True, node_size = 500) 
plt.show() 

enter image description here

В случае, если вы хотели бы использовать старые этикетки для рисования, например, то вы можете иметь другой словарь, который является обратный к new_lables, который просто сопоставляет новые метки старым. Вот как это можно сделать так:

# This can be used if you want to keep the old labels for drawing purpose for instance 
old_labels = dict ((y,x) for x,y in new_labels.iteritems()) 
nx.draw_networkx(G, labels = old_labels, with_labels=True, node_size = 500) 
plt.show() 

enter image description here

0

NetworkX держит узлы и ребро графа в словарной структуре, в которой узел является ключевым, и его данные является ассоциированной структурой словаря.По-видимому, когда вы читаете pajek формат файла, передаваемое ваш пример файла, dictionnary это одна:

>>> G = nx.read_pajek("test.pj") 
>>> pprint(G.node) 
{u'Author1': {'id': u'123'}, 
u'Author2': {'id': u'456'}, 
u'Author3': {'id': u'789'}, 
u'Author4': {'id': u'111'}, 
u'Author5': {'id': u'222'}, 
u'Author6': {'id': u'333'}} 

Это означает узел u'Author1' связан с данными {'id': u'123'}

Теперь, я не знаю, в файле Pajek формат, поле должно быть фактический узел (возможно, это не правильно реализован в NetworkX?), но если вы реверс имена и идентификаторы в файле вы получите то, что вы хотите:

*Network 
*Vertices 6 
    Author1 123 
    Author2 456 
    Author3 789 
    Author4 111 
    Author5 222 
    Author6 333 
*Edges 
    123 333 
    333 789 
    789 222 

и

>>> G = nx.read_pajek("test.pj") 
>>> pprint(G.node) 
{u'111': {'id': u'Author4'}, 
u'123': {'id': u'Author1'}, 
u'222': {'id': u'Author5'}, 
u'333': {'id': u'Author6'}, 
u'456': {'id': u'Author2'}, 
u'789': {'id': u'Author3'}} 
>>> G.node['111'] 
{'id': u'Author4'} 

Кроме того, идентификатор узла представляет собой строку, а не целое число. Если вам нужно целое число, вам может понадобиться перемаркировать узлы.

Смежные вопросы