How to get the data for the edge between two nodes? - python

I want to get the edge between two nodes in a networkx graph. More specifically, I want to get some data associated with this edge. I know a priori that these two nodes are linked. Is there a function to do this?

The edge data are stored in a dictionary. To access that dictionary, use get_edge_data().
import networkx as nx
G=nx.Graph()
G.add_edge(1,2, weight=5)
G.get_edge_data(1,2)
> {'weight': 5}
If you want to iterate through all the edges you can use G.edges(data=True)
H = nx.Graph()
H.add_edge(2, 3, color = 'red')
H.add_edge(1, 2, weight = 4)
for u,v,data in H.edges(data=True):
print(u, v, data)
> 1 2 {'weight': 4}
> 2 3 {'color': 'red'}

Related

How do I add weights for edges, when I specified multiple edges, not just 1 specific edge? Networkx

For the following code:
import networkx as nx
import matplotlib.pyplot as plt
G = nx.DiGraph()
#Set 1
G.add_edges_from([('A','B'),('A','C'),('C','B')])
#Set 2
G.add_edges_from([('D','A'),('D','B'),('D','C')])
#Set 3
G.add_edges_from([('E','D'),('E','B'),('E','C')])
pos = nx.spring_layout(G)
nx.draw_networkx_nodes(G,pos, node_size=500, node_color = 'green')
nx.draw_networkx_edges(G,pos, edgelist = G.edges())
plt.show()
I want to add weights to the edges. To my understanding, the weights are just 1 for all the edges. I want to modify the weights of every single edge in the graph.
From the follow documentation, I see that you can change the weight of a single node by adding :
https://networkx.org/documentation/stable/reference/generated/networkx.linalg.attrmatrix.attr_sparse_matrix.html
I want to add different weights to each edge. For example, ('A','B') is 0.1 weight, ('A', 'C') is 0.2 weight, etc.
I also looked at the following post:
NetworkX: how to add weights to an existing G.edges()?
However, it looks like they are iterating through each edge for a specific weight for all all edges, which is not what I want, rather I want specific weights for specific edges.
When adding the edges one can specify a dictionary containing arbitrary edge properties:
from networkx import DiGraph
G = DiGraph()
G.add_edges_from([('A','B', {'weight': 0.1}),('A','C', {'weight': 0.2})])
print(G.edges(data=True))
# [('A', 'B', {'weight': 0.1}), ('A', 'C', {'weight': 0.2})]
Alternatively, one can specify a triplet, where the first two elements are source/destination and the third element is weight, and then use the .add_weighted_edges_from method:
from networkx import DiGraph
G = DiGraph()
G.add_weighted_edges_from([('A','B', 0.1),('A','C', 0.2)])
print(G.edges(data=True))
# [('A', 'B', {'weight': 0.1}), ('A', 'C', {'weight': 0.2})]

Networkx: Interconnect nodes between two graphs

I have graph A. For every node in Graph A, I use some rules to convert the name of the node and decide to add it to Graph B.
So now I have B derived from A. I was wondering if it is possible to create some sort of link between the original node in A and the transformed node in B.
I couldn't figure out a method to do it using networkx library. Any pointers would be helpful...
Nodes can have attributes. In each node in graph A, you can create an attribute to hold the corresponding node in graph B.
In the code below, graph A has 3 nodes: 1, 2, and 3. Graph B is created with nodes 1, 4, and 9 (the squares of the values of the nodes in A). As each node in B is created, its value is stored in the b_node attribute of the A-node that originated it.
import networkx as nx
def main():
# Create graph A
a = nx.Graph()
a.add_node(1)
a.add_node(2)
a.add_node(3)
# Create graph B with nodes that are squares of the nodes in A
# Add to each node in A an attribute (b_node)
# to hold the corresponding node in B
b = nx.Graph()
for node in a:
a.add_node(node, b_node=node * node)
b.add_node(node * node)
print("A:")
print(a.nodes.data())
print("\nB:")
print(b.nodes.data())
if __name__ == '__main__':
main()
Output:
A:
[(1, {'b_node': 1}), (2, {'b_node': 4}), (3, {'b_node': 9})]
B:
[(1, {}), (4, {}), (9, {})]

partition graph into sungraphs based on node's attribute NetworkX

I'm using Networkx to compute some measures of a graph such as diameter, clustering coefficient, etc. It's straight forward how to do this for graph as a whole. What I'm interested in is finding these measures between nodes that have same attribute(say color). I'm thinking if I could partition the graph into different sub graphs, where nodes in each sub graph are of the same color, then I could accomplish go ahead and measure diameter in this sub graph. So my question is: Is there a way to partition a graph into sub graphs which contain nodes of same color?
I would really appreciate any insight.
Use Graph.subgraph(nodes)
NetworkX 2.x+:
Demo
import networkx as nx
G = nx.Graph()
G.add_nodes_from([1, 2, 3], color="red")
G.add_nodes_from([4, 5, 6])
G.nodes # NodeView((1, 2, 3, 4, 5, 6))
# create generator
nodes = (
node
for node, data
in G.nodes(data=True)
if data.get("color") == "red"
)
subgraph = G.subgraph(nodes)
subgraph.nodes # NodeView((1, 2, 3))
older NetworkX's
Iterate over (Graph.iter_nodes()) and filter the nodes based on your criteria. Pass that list to Graph.subgraph() and it'll return a copy of those nodes and their internal edges.
For example:
G = nx.Graph()
# ... build or do whatever to the graph
nodes = (n for n, d in G.nodes_iter(data=True)) if d.get('color') == 'red')
subgraph = G.subgraph(nodes)

Is there a way to run pagerank algorithm on NetworkX's MultiGraph?

I'm working on a graph with multiple edges between the same nodes (edges are having different values). In order to model this graph I need to use MultiGraph instead of normal Graph. Unfortunately, it's not possible to run PageRank algo on it.
Any workarounds known ?
NetworkXNotImplemented: not implemented for multigraph type
You could create make a graph without parallel edges and then run pagerank.
Here is an example of summing edge weights of parallel edges to make a simple graph:
import networkx as nx
G = nx.MultiGraph()
G.add_edge(1,2,weight=7)
G.add_edge(1,2,weight=10)
G.add_edge(2,3,weight=9)
# make new graph with sum of weights on each edge
H = nx.Graph()
for u,v,d in G.edges(data=True):
w = d['weight']
if H.has_edge(u,v):
H[u][v]['weight'] += w
else:
H.add_edge(u,v,weight=w)
print H.edges(data=True)
#[(1, 2, {'weight': 17}), (2, 3, {'weight': 9})]
print nx.pagerank(H)
#{1: 0.32037465332634, 2: 0.4864858243244209, 3: 0.1931395223492388}
You can still compose a Digraph by combining the edges
while adding their weights.
# combining edges using defaultdict
# input-- combined list of all edges
# ouput-- list of edges with summed weights for duplicate edges
from collections import defaultdict
def combine_edges(combined_edge_list):
ddict = defaultdict(list)
for edge in combined_edge_list:
n1,n2,w = edge
ddict[(n1,n2)].append(w)
for k in ddict.keys():
ddict[k] = sum(ddict[k])
edges = list(zip( ddict.keys(), ddict.values() ) )
return [(n1,n2,w) for (n1,n2),w in edges]

How do I get nodes from the specific edge in the networkx?

I want to compare nodes of different edges in the graph. How can I get the nodes(n1 and n2) from the edge(n1,n2)?
An edge in NetworkX is defined by its nodes, so I'm not really sure what you're asking here. A specific edge in the graph is just a tuple of nodes, with an optional weighting.
import networkx as nx
g = nx.Graph()
g.add_edge(1,2)
g.add_edge(2,3)
g.edges()
gives
[(1, 2), (2, 3)]
As you can see, the list of edges explicitly provides the nodes of each edge.
Update: Does this do what you want?
#!/usr/bin/python
import networkx as nx
import random
g = nx.Graph()
g.add_edges_from([(1,2),(2,3),(1,4),(2,5)])
random_edge = random.choice(g.edges())
print 'Randomly selected edge is:', random_edge
print 'Nodes are', random_edge[0], 'and', random_edge[1]
The answer to what I think was the intended question is:
graph = networkx.read_graphml('some_fully_loaded_graph.graphml')
edge0 = list(graph.edges(data=True))[0]
subgraph = graph.edge_subgraph([edge0[:2]])
nodes0 = list(subgraph.nodes(data=True))

Categories