使用字符串

时间:2015-12-03 05:54:12

标签: python networkx

我正在使用带有Python的NetworkX库。

我希望能够通过仅使用作为节点名称(字符串)一部分的int ID来引用节点,以实现各种目的,例如获取两个节点之间的最短路径。

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只使用其id为111?

到目前为止,我已经尝试过G.node [nodeid]的格式,例如:

print G.node[111]

但是这会返回错误,因为它试图搜索节点LABEL = 111,这当然不存在。

作为一个后续问题,理想情况下,我不仅要按ID打印节点,还要将其用于函数,例如

nx.shortest_path_length(G,source_nodeid,target_nodeid)

我目前正在做的工作是创建一个.net网络文件,其中节点ID列重复两次,以便使用相同的ID号作为"节点标签"太

我确定答案必须非常简单,但到目前为止它已经逃过了我,即使经过Google搜索并浏览文档...... 任何帮助将不胜感激!

2 个答案:

答案 0 :(得分: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

答案 1 :(得分:0)

networkx将图形的节点和边缘保持在以节点为关键字的字典结构中,并且其数据是关联的字典结构。显然,当您阅读给出示例文件的pajek文件格式时,字典是这样的:

>>> 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中没有正确实现?),但是如果你反转你的名字和ID文件你得到你想要的:

*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'}

此外,节点id是一个字符串,而不是整数。如果需要整数,则可能需要重新标记节点。