Simultaneously create attributes and edges (if sam

2019-07-18 22:07发布

After creating nodes in NetworkX, I would like add edges between nodes if both nodes have (at least) one overlapping same attribute. It seems to be a problem that not all nodes contain the same number of attributes - could this be the case, and if so, how should I solve it?

import networkx as nx
from itertools import product

# Mothernodes
M = [('E_%d' % h, {'a': i, 'b': j, 'c': k, 'd': l})
 for h, (i, j, k, l) in enumerate(product(range(2), repeat=4), start=1)]

# children nodes
a = [ (  'a_%d' % i, {'a' : i}) for i in range(0,2)  ]
b = [ (  'b_%d' % i, {'b' : i}) for i in range(0,2)  ]
c = [ (  'c_%d' % i, {'c' : i}) for i in range(0,2)  ]
d = [ (  'd_%d' % i, {'d' : i}) for i in range(0,2)  ]


# graph containing both
M_c = nx.Graph()
M_c.add_nodes_from(M)

ls_children = [a, b, c , d]
for ls_c in ls_children:
    M_c.add_nodes_from(ls_c)

list(M_c.nodes(data=True))[0:20]

[('E_9', {'a': 1, 'b': 0, 'c': 0, 'd': 0}),
 ('d_0', {'d': 0}),
 ('E_10', {'a': 1, 'b': 0, 'c': 0, 'd': 1}),
 ('b_0', {'b': 0}),
 ('E_2', {'a': 0, 'b': 0, 'c': 0, 'd': 1}),
 ('E_1', {'a': 0, 'b': 0, 'c': 0, 'd': 0}),
 ('c_1', {'c': 1}),
 ...
    ] 

# attempting to add edges if one attribute is overlapping/the same: 
for start in M_c.nodes(data=True):
    for end in M_c.nodes(data=True):
       for attr in list(start[1].keys()):
            if start[1][attr] == end[1][attr]:
                M_c.add_edge(start[0] ,end[0] )


 ---------------------------------------------------------------------------
 KeyError                                  Traceback (most recent call last)
 <ipython-input-4-22b88809e853> in <module>()
       2     for end in M_c.nodes(data=True):
       3         for attr in list(start[1].keys()):
 ----> 4             if start[1][attr] == end[1][attr]:
       5                 M_c.add_edge(start[0] ,end[0] )

 KeyError: 'b'

EDIT2:

I have now tried to test both start and end for existence of attributes, but I still get an error:

for start in M_c.nodes(data=True):
    for end in M_c.nodes(data=True):
        for attr in list(start[1].keys()):
            if start[1][attr]:
                if end[1][attr]:
                    if start[1][attr] == end[1][attr]:
                        M_c.add_edge(start[0], end[0] )
    # Adding an else and continue statement does not affect the error, 
    # even adding three of them, for each if statement
    #        else:
    #            continue

---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
<ipython-input-5-32ae2a6095e5> in <module>()
      3         for attr in list(start[1].keys()):
      4             if start[1][attr]:
----> 5                 if end[1][attr]:
      6                     if start[1][attr] == end[1][attr]:
      7                         M_c.add_edge(start[0], end[0] )

KeyError: 'a'

1条回答
三岁会撩人
2楼-- · 2019-07-18 22:26

Creating edges between nodes sharing the same attribute value

import networkx as nx
import random
import matplotlib.pyplot as plt

# create nodes
G = nx.Graph()
_ = [G.add_node(i, a=random.randint(1,10), 
                   b=random.randint(1,10), 
                   c=random.randint(1,10)) for i in range(20)]

for node in G.nodes(data=True):
    print(node)

[out:]

(0, {'a': 10, 'b': 10, 'c': 3})
(1, {'a': 10, 'b': 6, 'c': 2})
(2, {'a': 4, 'b': 5, 'c': 5})
(3, {'a': 5, 'b': 10, 'c': 8})
(4, {'a': 3, 'b': 10, 'c': 8})
(5, {'a': 7, 'b': 1, 'c': 9})
(6, {'a': 10, 'b': 8, 'c': 8})
(7, {'a': 7, 'b': 7, 'c': 2})
(8, {'a': 6, 'b': 3, 'c': 9})
(9, {'a': 1, 'b': 5, 'c': 7})
(10, {'a': 3, 'b': 2, 'c': 8})
(11, {'a': 4, 'b': 1, 'c': 6})
(12, {'a': 3, 'b': 10, 'c': 3})
(13, {'a': 4, 'b': 5, 'c': 3})
(14, {'a': 7, 'b': 10, 'c': 4})
(15, {'a': 1, 'b': 1, 'c': 10})
(16, {'a': 1, 'b': 9, 'c': 1})
(17, {'a': 3, 'b': 8, 'c': 4})
(18, {'a': 6, 'b': 8, 'c': 7})
(19, {'a': 7, 'b': 10, 'c': 4})

Creating edges

for start in G.nodes(data=True):
    for end in G.nodes(data=True):
        for attr in list(start[1].keys()):
            if start[1][attr] == end[1][attr]:
                G.add_edge(start[0] ,end[0] )

Plotting the network

pos = nx.spring_layout(G)
nx.draw_networkx_nodes(G, pos)
nx.draw_networkx_edges(G,pos)
nx.draw_networkx_labels(G,pos, font_color='w')
plt.axis('off')
plt.show()

resulting_network

查看更多
登录 后发表回答