How to add edge weights from one graph to matching edges in a different graph in NetworkX?

Viewed 175

I have two different graphs in networkx, one graph has a total collection of edges. The other graph is a subset of the total edges. How would I take the weights from the total collection of edges graph and add them to matching edges in the new graph?

#total edge collection
G.edges(data = True)

OutEdgeDataView([(1, 2, {'weight': 10}), (2, 3, {'weight': 0}), (2, 5, {'weight': 0}), (2, 6, {'weight': 0}), 
(2, 1, {'weight': 0}), (3, 4, {'weight': 10}), (3, 7, {'weight': 0}), (3, 8, {'weight': 0}), (3, 2, {'weight': 0}), (4, 3, {'weight': 0}), (5, 2, {'weight': 0}), (6, 2, {'weight': 0}), 
(7, 3, {'weight': 0}), (8, 3, {'weight': 0})])
T = nx.Graph()
T.add_edges_from([(1, 2), (2, 3), (2, 5), (2, 6), (3, 8), (3, 4), (3, 7)])
T.edges(data = True)

EdgeDataView([(1, 2, {}), (2, 3, {}), (2, 5, {}), (2, 6, {}), (3, 8, {}), (3, 4, {}), (3, 7, {})])

I would want the T EdgeDataView to look like

EdgeDataView([(1, 2, {'weight':10}), (2, 3, {'weight': 0}), (2, 5, {'weight': 0}), (2, 6, {'weight': 0}),
 (3, 8, {'weight': 0}), (3, 4, {'weight': 10}), (3, 7, {'weight': 0})])

Any ideas would be appreciated,

1 Answers

You may try the networkx Graph.edge_subgraph function.

For your example.
First creating the graph:

G = nx.DiGraph()
G.add_edges_from([(1, 2, {'weight': 10}), (2, 3, {'weight': 0}), (2, 5, {'weight': 0}), (2, 6, {'weight': 0}), 
(2, 1, {'weight': 0}), (3, 4, {'weight': 10}), (3, 7, {'weight': 0}), (3, 8, {'weight': 0}), (3, 2, {'weight': 0}), (4, 3, {'weight': 0}), (5, 2, {'weight': 0}), (6, 2, {'weight': 0}), 
(7, 3, {'weight': 0}), (8, 3, {'weight': 0})])

Next, choose the nodes you pretend to add to a new graph:

edge_set = [(1, 2), (2, 3), (2, 5), (2, 6), (3, 8), (3, 4), (3, 7)]

Then, extract the edges from one graph to the other:

Di_T = G.edge_subgraph(edge_set)

Note that since G is directed T will also be directed, so:

T = Di_T.to_undirected()    # see NOTE in the end

Result

>>> T.edges(data = True)

EdgeDataView([ (1, 2, {'weight': 10}),
               (2, 3, {'weight': 0}),
               (2, 5, {'weight': 0}),
               (2, 6, {'weight': 0}),
               (3, 4, {'weight': 10}),
               (3, 7, {'weight': 0}),
               (3, 8, {'weight': 0})])

full code:

# example graph

G = nx.DiGraph()
G.add_edges_from([(1, 2, {'weight': 10}), (2, 3, {'weight': 0}), (2, 5, {'weight': 0}), (2, 6, {'weight': 0}), (2, 1, {'weight': 0}), (3, 4, {'weight': 10}), (3, 7, {'weight': 0}), (3, 8, {'weight': 0}), (3, 2, {'weight': 0}), (4, 3, {'weight': 0}), (5, 2, {'weight': 0}), (6, 2, {'weight': 0}), (7, 3, {'weight': 0}), (8, 3, {'weight': 0})])


# example edge set

edge_set = [(1, 2), (2, 3), (2, 5), (2, 6), (3, 8), (3, 4), (3, 7)]


# solution

T = G.edge_subgraph(edge_set).to_undirected()
T.edges(data = True)

NOTE:

Usually a copy is made of G.edge_subgraph(edge_set) (using .copy) in order to obtain a new copy of the graph instead of a reference of the original graph(see the notes in the Docs).
However, .to_undirected already makes a deep copy of the graph so there is no need for .copy, check G.edge_subgraph and .to_undirected documentations for more info

Related