문제 설명
문자열의 int 부분으로 문자열 레이블의 노드에 액세스 (Access a node of string label with an int part of the string)
Python과 함께 NetworkX 라이브러리를 사용하고 있습니다.
다양한 노드 이름(문자열)의 일부인 int ID만 사용하여 노드를 참조할 수 있도록 하고 싶습니다. 두 노드 사이의 최단 경로를 가져오는 것과 같습니다.
MWE:
Pajek 형식의 파일을 가져왔다고 가정해 보겠습니다.
import networkx as nx
G=nx.read_pajek("pajek_network_file.net")
G=nx.Graph(G)
내용 내 파일은 (Pajek에서는 노드를 "Vertices"라고 함):
*Network
*Vertices 6
123 Author1
456 Author2
789 Author3
111 Author4
222 Author5
333 Author6
*Edges
123 333
333 789
789 222
ID 111만 사용하여 Author4 노드를 인쇄하려면 어떤 명령을 사용해야 합니까?
지금까지 , 다음과 같은 G.node[nodeid] 형식을 시도했습니다.
print G.node[111]
하지만 이것은 물론 존재하지 않는 노드 LABEL = 111을 검색하려고 시도하기 때문에 오류를 반환합니다.
다음 질문으로,이상적으로는 ID로 노드를 인쇄할 뿐만 아니라 다음과 같은 기능과 함께 사용하고 싶습니다.
nx.shortest_path_length(G,source_nodeid,target_nodeid)
현재 해결 방법은 .net 네트워크를 만드는 것입니다. "node label"과 동일한 id 번호를 사용하기 위해 node id 열이 두 번 반복되는 파일.
답은 매우 간단할 것이라고 확신하지만 지금까지는 탈출했습니다. 인터넷 검색을 많이 하고 문서를 살펴본 후에도... 도움을 주시면 감사하겠습니다!
나는 대답이 매우 간단할 것이라고 확신하지만, 구글링을 많이 하고 문서를 살펴본 후에도 지금까지는 그냥 탈출했습니다... 어떤 도움이라도 주시면 감사하겠습니다!나는 대답이 매우 간단할 것이라고 확신하지만, 구글링을 많이 하고 문서를 살펴본 후에도 지금까지는 그냥 탈출했습니다... 어떤 도움이라도 주시면 감사하겠습니다!참조 솔루션
방법 1:
I believe you are looking for nx.relabel_nodes function which takes a dictionary to map old labels to new labels. I used vertices names you provided to build the graph. Then created a dictionary which maps the old labels (full string) to new labels (integer cast of the first element of the string after splitting it). Finally, I used the relabel_nodes function to do the relabelling.
Here is how I used it to solve your problem:
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()
In case you would like to use the old labels for drawing for example then you can have another dictionary which is the inverse of the new_lables that simply maps the new labels to the old ones. Here is how you might do so:
# 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()
방법 2:
networkx keeps the nodes and edges of the graph in a dictionary structure where the node is the key, and its data is an associated dictionary structure. Apparently when you read the pajek file format given your example file, the dictionnary is this one:
>>> 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'}}
Which means node u'Author1'
is associated with data {'id': u'123'}
Now, I don't know in the Pajek file format which field is supposed to be the actual node (maybe it's not implemented correctly in networkx?), but if you reverse names and ids in your file you get what you want:
*Network
*Vertices 6
Author1 123
Author2 456
Author3 789
Author4 111
Author5 222
Author6 333
*Edges
123 333
333 789
789 222
and
>>> 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'}
Moreover, the node id is a string, not an integer. If you need an integer, you may need to relabel the nodes.
(by elvitaluz、Abdallah Sobehy、Emilien)