Networkx с ошибками при добавлении узлов и ребер - PullRequest
0 голосов
/ 24 октября 2018

Это простая программа на Python для генерации сетевого графа.Все было хорошо, когда я поместил данные в программу, но когда я решил поместить данные в два входных файла, все стало интересным.Есть два входных файла: узлы (или вершины) и ребра.Когда я прочитал информацию об узлах из входных файлов, называемых «Step3-Vertices.txt», это не дало никакой ошибки, но к узлам, которые я не предоставил, была добавлена ​​дополнительная информация.Вот список дополнительной информации: '[', '{', "'", '0', '2', ',', ' ', '6', '8', 'W', '}', '.', '1', '5', '3', '7', '4', 'O', 'X', 'D', ']', '\n'

Затем я прочитал во 2-м файле с именем '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 Ответ

0 голосов
/ 24 октября 2018

Формат, ожидаемый add_edges_from, представляет собой список кортежей в его наиболее простой форме в виде списка (u, v) пар для подключения.

Ваши файлы не имеют данных в соответствующей форме, поэтому networkx не знает, что с ними делать.Если текст в точности соответствует тому, что вы написали в переменной «dge », то ниже приведен один из способов вписать его в правильный список.Вы можете сделать то же самое для обработки узла, хотя для этого нужен только список элементов, а не список кортежей, так что это более просто.

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

, который описывает, как читать из различных стандартных форматов графиков.


РЕДАКТИРОВАТЬ после комментария:

Причина, по которой у вас много "неожиданных" узлов в графе, заключается в том, что 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...