Lee Yaan
Lee Yaan

Reputation: 547

Parse a file to create a graph in python

i have a file with format like this(but its a bigger file):

13  16  1
11  17  1
8   18  -1
11  19  1
11  20  -1
11  21  1
11  22  1

The first column is the starting vertex, the second column is the ending vertex and the third is the weight between the starting and ending vertex.

I try to create a graph with networkx but im getting this error:

"Edge tuple %s must be a 2-tuple or 3-tuple." % (e,))

Here is my code:

import networkx as nx

file = open("network.txt","r")
lines = file.readlines()
start_vertex = []
end_vertex = []
sign = []

for x in lines:
    start_vertex.append(x.split('\t')[0])
    end_vertex.append(x.split('\t')[1])
    sign.append(x.split('\t')[2])
file.close()

G = nx.Graph()

for i in lines:
    G.add_nodes_from(start_vertex)
    G.add_nodes_from(end_vertex)
    G.add_edges_from([start_vertex, end_vertex, sign])

Upvotes: 0

Views: 1320

Answers (2)

Prateek
Prateek

Reputation: 73

Use the networkx library of python .. (I am assuming Python 3.6).

The following code will read your file as is. You won't need the lines you have written above.
The print command that I have written is to help you check if the graph which has been read is correct or not.

Note: If your graph is not a directed graph then you can remove the create_using=nx.DiGraph() part written in the function.

import networkx as nx
g = nx.read_edgelist('network.txt', nodetype=int, data=(('weight', int),), create_using=nx.DiGraph(),delimiter='  ')
print(nx.info(g))

Upvotes: 1

Joel
Joel

Reputation: 23907

You should use networkx's read_edgelist command.

G=nx.read_edgelist('network.txt', delimiter = '  ', nodetype = int, data = (('weight', int),))

notice that the delimiter I'm using is two spaces, because this appears to be what you've used in your input file.


If you want to stick to your code:

First, get rid of for i in lines.

The reason for your error is twofold. First, you want to use G.add_weighted_edges_from rather than G.add_edges_from.

Also, this expects a list (or similar object) whose entries are of the form (u,v,weight). So for example, G.add_weighted_edges_from([(13,16,1), (11,17,1)]) would add your first two edges. It sees the command G.add_weighted_edges_from([[13,11,8,11,...],[16,17,18,19,...],[1,1,-1,1,...]) and thinks that [13,11,8,11,...] needs to be the information for the first edge, [16,17,18,19,...] is the second edge and [1,1,-1,1,...] is the third edge. It can't do this.

You could do G.add_weighted_edges_from(zip(start_vertex,end_vertex,sign)). See this explanation of zip: https://stackoverflow.com/a/13704903/2966723


finally, G.add_nodes_from(start_vertex) and G.add_nodes_from(end_vertex) are unneeded. If the nodes don't exist already when networkx tries to add an edge it will add the nodes as well.

Upvotes: 2

Related Questions