Contracted nodes automatically in Networkx

Tags: , , , ,



I have problem, I wish could automatically merge the nodes by inserting an if condition.

I have this dataframe:

            Individuals       Weight    Source  Destination
0   (10.0.12.100, 10.0.1.1)     24  10.0.12.100 10.0.1.1
1   (10.0.1.1, 10.0.11.100)     24  10.0.1.1    10.0.11.100
2   (10.0.11.100, 10.0.1.2)     22  10.0.11.100 10.0.1.2
3   (10.0.1.2, 10.0.12.100)     17  10.0.1.2    10.0.12.100
4   (10.0.13.100, 10.0.1.17)    17  10.0.13.100 10.0.1.17
5   (10.0.1.17, 10.0.1.5)       11  10.0.1.17   10.0.1.5
6   (10.0.1.5, 10.0.11.100)     21  10.0.1.5    10.0.11.100
7   (10.0.11.100, 10.0.1.6)     16  10.0.11.100 10.0.1.6
8   (10.0.1.6, 10.0.1.18)       13  10.0.1.6    10.0.1.18
9   (10.0.1.18, 10.0.13.100)    9   10.0.1.18   10.0.13.100
10  (10.0.1.18, 10.0.1.26)      16  10.0.1.18   10.0.1.26
11  (10.0.1.26, 10.0.14.100)    42  10.0.1.26   10.0.14.100
12  (10.0.14.100, 10.0.1.22)    16  10.0.14.100 10.0.1.22
13  (10.0.1.22, 10.0.1.9)       12  10.0.1.22   10.0.1.9
14  (10.0.1.9, 10.0.12.100)     14  10.0.1.9    10.0.12.100
15  (10.0.1.1, 10.0.1.6)        42  10.0.1.1    10.0.1.6
16  (10.0.13.100, 10.0.1.26)    15  10.0.13.100 10.0.1.26
17  (10.0.1.5, 10.0.1.2)        28  10.0.1.5    10.0.1.2
18  (10.0.14.100, 10.0.1.25)    25  10.0.14.100 10.0.1.25
19  (10.0.1.25, 10.0.1.17)      11  10.0.1.25   10.0.1.17
20  (10.0.12.100, 10.0.1.11)    19  10.0.12.100 10.0.1.11
21  (10.0.1.11, 10.0.1.23)      17  10.0.1.11   10.0.1.23
22  (10.0.1.23, 10.0.14.100)    18  10.0.1.23   10.0.14.100
23  (10.0.1.25, 10.0.13.100)    24  10.0.1.25   10.0.13.100

I created this graph:

enter image description here

What I would like is to merge the nodes with Weight <15 and not taking the nodes 10.0.11.100,10.0.12.100,10.0.13.100,10.0.14.100 using an if condition.

I tried with this code:

if G1.nodes != "10.0.12.100" and  G1.nodes != "10.0.11.100" and  G1.nodes != "10.0.13.100" and  G1.nodes != "10.0.14.100" and G1.edges['Weight'] < 15:
  G1 = nx.contracted_nodes(G1, *G1.nodes)

But it does not work. I wish it were all automatic, without me entering the nodes by hand like this::

G1 = nx.contracted_nodes(G1,"10.0.1.22","10.0.1.9",self_loops=False)
G1 = nx.contracted_nodes(G1,"10.0.1.6","10.0.1.18",self_loops=False)
etc

This is my code:

G1 = nx.from_pandas_edgelist(output, 'Source', 'Destination', ['Weight'])

plt.figure(3,figsize=(12,12)) 
pos = nx.spring_layout(G1) # positions for all nodes
nx.draw(
    G1,
    pos=pos,
    node_color='#FF0000',
    with_labels=True
)
labels = {e: G1.edges[e]['Weight'] for e in G.edges}
nx.draw_networkx_edge_labels(G1, pos, edge_labels=labels)

if (G1.nodes != "10.0.12.100") and  (G1.nodes != "10.0.11.100") and  (G1.nodes != "10.0.13.100") and  (G1.nodes != "10.0.14.100") and (G1.edges['Weight'] < 15):
  G1 = nx.contracted_nodes(G1, *G1.nodes)

Thanks

Answer

IIUC, you can use a for loop like this:

restrict_nodes = ['10.0.11.100', '10.0.12.100', '10.0.13.100', '10.0.14.100']
for i in G1.edges(data=True):
     if i[2]['Weight'] < 15 and i[0] not in restrict_nodes:
         G1 = nx.contracted_nodes(G1, i[0], i[1], self_loops=False)

plt.figure(3,figsize=(12,12)) 
pos = nx.spring_layout(G1) # positions for all nodes
nx.draw(
    G1,
    pos=pos,
    node_color='#FF0000',
    with_labels=True
)
labels = {e: G1.edges[e]['Weight'] for e in G1.edges}
nx.draw_networkx_edge_labels(G1, pos, edge_labels=labels)


Source: stackoverflow