添加节点和边时出现错误的Networkx

3
这是一个简单的Python程序,用于生成网络图。当我将数据放入程序中时一切正常,但当我决定将数据放入两个输入文件中时,事情就变得有趣了起来。有两个输入文件:节点(或顶点)和边。当我从名为“Step3-Vertices.txt”的输入文件中读取节点信息时,它没有出现任何错误,但是添加了一些我没有提供的附加信息到节点中。以下是附加信息的列表: '[', '{', "'", '0', '2', ',', ' ', '6', '8', 'W', '}', '.', '1', '5', '3', '7', '4', 'O', 'X', 'D', ']', '\n' 然后我读取了第二个名为“Step3-Edges.txt”的文件,这次我得到了一系列我无法理解的错误消息。
错误消息 - 当从文件添加边信息时,NETWORKX失败:
Traceback (most recent call last):
File "step4_test1.py", line 30, in <module>
G.add_edges_from(data_edges)
File "/home/desmond/anaconda3/lib/python3.6/site-packages/networkx/classes/graph.py", line 934, in add_edges_from
"Edge tuple %s must be a 2-tuple or 3-tuple." % (e,))
networkx.exception.NetworkXError: Edge tuple [ must be a 2-tuple or 3-tuple.

请问有人可以帮我吗?

这是我的程序:

""" THIS PROGRAM WORKS PROPERLY WHEN DATA ARE PASSED TO LOCAL VARIABLES CALLED "nodes" and "edges".  THE EXACT DATA ARE ALSO STORED IN TWO FILES: "nodes" in 'Step3-Vertices.txt' and "edges" in 'Step3-Edges.txt'.  PROBLEMS STARTED WHEN NODES AND EDGES ARE READ FROM BOTH FILES.  FIRST, RUN THIS PROGRAM AND IT SHOULD GENERATE A GRAPH.  THEN REPLACE THE "nodes" with "data_nodes" in "G.add_nodes_from" AND THIS WILL GENERATE UNEXPECTED ADDITIONAL NODES WHICH ARE NOT SUPPOSED TO BE THERE.  NEXT, REPLACE THE "edges" with "data_edges" in "G.add_nodes_from" AND ERROR MESSAGES ARE DISPLAYED."""  


import networkx as nx
import matplotlib.pyplot as plt



""" READ NODES INFORMATION FROM FILE """

with open('Step3-Vertices.txt', encoding='utf-8') as data_file:
    data_nodes = data_file.read()

print(data_nodes)

""" READ EDGESS INFORMATION FROM FILE """


with open('Step3-Edges.txt', encoding='utf-8') as data_file:
    data_edges = data_file.read()

print(data_edges)


G=nx.Graph()

"""  PASS NODES INFORMATION TO A VARIABLE CALLED 'nodes'   """

nodes = ['0000000002', '0000000101', '0000000111', '0000000200', '0000000502', '0000000600', '0000001000', '0000001001', '0000001069', '0000001253', '0000001462', '0000003013', '0000003200', '0000004100', '0000004305', '0000005100', '0000005460', '0000006600', '0000010021', '0000010101', '0000010200', '0000010314', '0000012000', '0000012151', '0000012600', '0000015201', '0000016100', '0000017002', '0000020002', '0000020050', '0000020100', '0000021001', '0000022044', '0000022100']


""" PASS EDGES INFORMATION TO A VARIABLE CALLED 'edges'   """

edges = [{'0000000002', '6080022W'}, {'80.015.012.210', '0000000002'}, {'80.015.012.210', '0000000502'}, {'0000012000', '0000000502'},{'0000000101', '012.105.123.127'}, {'0000000111', '2442032O'}, {'105.103.02.110', '0000000111'}, {'0604054X', '0000000200'}, {'100.001.008.002', '0000000200'}, {'0000000502', '1002567D'}, {'208.08.032.1', '0000000502'}]

"""THIS IS WHERE YOU ADD DATA TO THE NODES AND EDGES, BY DEFAULT, LOCAL VARIABLES ARE USED. TO ADD DATA FROM THE INPUT FILES - replace 'nodes' with 'data_nodes' and replace 'edges' with 'data_edges'   """




G.add_nodes_from(nodes)
G.add_edges_from(edges)

print("Nodes of graph: ")
print(G.nodes())


print("Edges of graph: ")
print(G.edges())

###  DRAW A GRAPH  ###

nx.draw(G)
plt.savefig("test1.png") # save as png
plt.show() # display
1个回答

4
add_edges_from所期望的格式是一个元组列表,最基本的形式是一组(u,v)对作为连接。你的文件中的数据格式不合适,因此networkx不知道该怎么处理它们。如果“edges”变量中的文本正好是您编写的内容,则下面是将其转换为正确类型列表的一种方法。您可以类似地进行节点处理,尽管这只需要一个元素列表,而不是元组列表,因此更加简单明了。
with open("edgefile.txt") as data_file:
    data_edges = data_file.read()

# split on the comma, assuming this divides elements, remove the curly braces and quotes
elems = ([f.strip(" {}'") for f in data_edges.strip().split(',')])
# use zip to turn the flat list into a lst of pairs
edge_list = zip(elems[::2], elems[1::2])

# now we are in a form that nx.add_edges_from can handle
G = nx.Graph()
G.add_nodes_from(nodes)
G.add_edges_from(edge_list)

您应该在此处阅读有关读取图形的文档:https://networkx.github.io/documentation/stable/reference/readwrite/index.html,其中描述了如何从各种标准图形格式中读取。
编辑:如评论中的qu所述,您之所以在图形中有许多“意外”的节点,是因为nx.add_nodes_from需要一个可迭代类型,并且当您将整个文件读入文本变量时,迭代该字符串会一次一个字符地进行。这导致单字符节点(例如0'\n)。因此,我们可以通过将字符串解析为列表来修复它,并且在列表上迭代给出一个元素,例如'0000000002'
这是一个示例:
# assume that the file describing nodes is read into this string:
node_txt = "'0000000002', '0000000101', '0000000111', '0000000200', '0000000502', '0000000600', '0000001000', '0000001001', '0000001069', '0000001253', '0000001462', '0000003013', '0000003200', '0000004100', '0000004305', '0000005100', '0000005460', '0000006600', '0000010021', '0000010101', '0000010200', '0000010314', '0000012000', '0000012151', '0000012600', '0000015201', '0000016100', '0000017002', '0000020002', '0000020050', '0000020100', '0000021001', '0000022044', '0000022100'\n"

G1 = nx.Graph()
G1.add_nodes_from(node_txt)
print(G1.nodes())
print(set(node_txt))
# output of these two commands shows that the node names are 1 char each:
>>> [' ', "'", '\n', ',', '1', '0', '3', '2', '5', '4', '7', '6', '9']
>>> set([' ', "'", '\n', ',', '1', '0', '3', '2', '5', '4', '7', '6', '9'])

# reference: what we really wanted    
node_list = ['0000000002', '0000000101', '0000000111', '0000000200', '0000000502', '0000000600', '0000001000', '0000001001', '0000001069', '0000001253', '0000001462', '0000003013', '0000003200', '0000004100', '0000004305', '0000005100', '0000005460', '0000006600', '0000010021', '0000010101', '0000010200', '0000010314', '0000012000', '0000012151', '0000012600', '0000015201', '0000016100', '0000017002', '0000020002', '0000020050', '0000020100', '0000021001', '0000022044', '0000022100']

G2  = nx.Graph()
G2.add_nodes_from(node_list)
print(G2.nodes())
print(set(node_list))

那么如何将node_txt转换为node_list的形式呢?我们按照上述边缘描述的相同过程进行 - 这个过程要简单一些。
elems = [f.strip(" '") for f in node_txt.strip().split(',')]
print(elems == node_list)
# output: True -> so here we recovered the node names correctly from node_txt

谢谢。我测试了你的代码,它在我的程序上运行良好。顺便问一下,我该如何处理Networkx生成的额外节点。当我从名为“Step3-Vertices.txt”的输入文件中读取节点信息时,没有出现任何错误,但是添加了我没有提供的附加信息到节点中。以下是附加信息列表:'[', '{',"'",'0','2',',',' ','6','8','W','}','.','1','5','3','7','4','O','X','D',']','\n'。这些额外节点对我没有用处。我不知道它们来自哪里。我该如何摆脱它们? - Des
问题与上述相同。我没有试图猜测节点文件的结构,但是当您使用<file>.read()时,Python会给您一个单一的字符串。上面的代码将由逗号分隔的元素列表转换为元组列表。对于节点列表,您可能需要做同样的事情。否则,该字符串将被解释为字符列表,并在G.add_nodes_from()中引发错误。 - Bonlenfum

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接