节点具有不同的属性长度,如果> = 1属性相同,则添加边 [英] Having nodes with differing lengths of attributes, add edges if >=1 attribute is the same

查看:103
本文介绍了节点具有不同的属性长度,如果> = 1属性相同,则添加边的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在NetworkX中,尝试完成以下任务:

In NetworkX 'm trying to accomplish the following:

  • 在一个图中创建"mother-nodes"和"children-nodes",其中子节点仅具有1个属性,而母节点具有多个(4).
  • 如果至少一个属性(键值对)相同,则在母节点和子节点之间创建边缘
  • 仅在母节点和子节点之间创建一条边缘:即使两个母节点具有4个重叠属性之一,两者之间也不应有边缘

到目前为止,我的第一部分正在工作,第二部分是

So far I have the first part working, and on the second one michaelg has been very helpful, but there is still an error.

import networkx as nx
from itertools import product

# Mother-nodes
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)

# what it looks like so far
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}),
 ...
    ] 

然后是第二部分,它会产生错误:

And then the second part, which generates 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'

我也许忽略了某些东西-任何建议都将不胜感激.

I am perhaps overlooking something - any suggestions are greatly appreciated.

EDIT-1:

正如杜克敏(ducminh)建议的那样,我跑了:

As suggested by ducminh I ran:

for mother_node in M:
    for child_node in chain(a, b, c, d):
        if child_node[1].items() <= mother_node[1].items():
            M_c.add_edge(child_node, mother_node)

哪个返回了此错误:

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-6-24f1a24a49e8> in <module>()
      2     for child_node in chain(a, b, c, d):
      3         if child_node[1].items() <= mother_node[1].items():
----> 4             M_c.add_edge(child_node, mother_node)
      5 

/usr/local/lib/python3.5/dist-packages/networkx/classes/graph.py in add_edge(self, u_of_edge, v_of_edge, **attr)
    873         u, v = u_of_edge, v_of_edge
    874         # add nodes
--> 875         if u not in self._node:
    876             self._adj[u] = self.adjlist_inner_dict_factory()
    877             self._node[u] = {}

TypeError: unhashable type: 'dict'

推荐答案

如果节点是父节点,则它始终具有所有4个属性a, b, c, d,而子节点仅具有一个属性.因此,可能情况是字典start[1]具有键attr,而end[1]没有键.

If a node is a mother node, it always has all 4 attributes a, b, c, d, while a child node only has one attribute. So it might be the case that the dict start[1] has the key attr, while end[1] does not.

要正确地在母节点和子节点之间添加边,我们需要遍历所有可能的对(母节点,子节点),然后检查子节点的属性决定是否是子节点的决定.母节点.

To correctly add edges between mother nodes and child nodes, we need to iterate over all possible pairs (mother node, child node), then check if the dict of attributes of the child node is a sub-dict of that of the mother node.

from itertools import chain

for mother_node in M:
    for child_node in chain(a, b, c, d):
        if child_node[1].items() <= mother_node[1].items():
            M_c.add_edge(child_node[0], mother_node[0])

这篇关于节点具有不同的属性长度,如果&gt; = 1属性相同,则添加边的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆