繁体   English   中英

从图中删除没有特定属性的节点时出错

[英]Error when removing nodes that do not have a certain attrubute from the graph

我用networkx生成了一个图表。 然后我将属性'commu_per'添加到一些节点。 然后想删除那些没有属性'commu_per'节点。

import urllib3
import io
import networkx as nx
from networkx.algorithms import community

## Import dataset
http = urllib3.PoolManager()
url = 'https://raw.githubusercontent.com/leanhdung1994/WebMining/main/lesmis.gml'
f = http.request('GET', url)
data = io.BytesIO(f.data)
g = nx.read_gml(data)

## Define a function to add attributes
def add_att(g, att, att_name):
    att = list(att)
    for i in g.nodes():
        for j in range(len(att)):
            if i in list(att[j]):
                nx.set_node_attributes(g, {i: j}, name = att_name)
                break

## Add attributes
commu_per = community.k_clique_communities(g, 3)   
add_att(g, commu_per, 'commu_per')

g_1 = g
## Remove nodes which do not have attribute 'commu_per'
for i in g.nodes:
    if 'commu_per' not in g.nodes[i]:
        g_1.remove_node(i)

然后它返回一个错误

---------------------------------------------------------------------------
RuntimeError                              Traceback (most recent call last)
<ipython-input-6-7339f3f2ea6a> in <module>
     26 g_1 = g
     27 ## Remove nodes which do not have attribute 'commu_per'
---> 28 for i in g.nodes:
     29     if 'commu_per' not in g.nodes[i]:
     30         g_1.remove_node(i)

RuntimeError: dictionary changed size during iteration

您能否详细说明如何解决此错误?

你 g 和 g1 dict 对象是相同的。 因此,在 1 上获得一个迭代器并使用它来尝试删除另一个是行不通的。

>>> a  = {1:10, 2:20}
>>> b  = a
>>> id(b) == id(a)
True
>>> b[4] = 40
>>> id(b) == id(a)
True
>>> b
{1: 10, 2: 20, 4: 40}
>>> a
{1: 10, 2: 20, 4: 40}
>>> 

使用 copy() 方法获取新副本,以便您可以在迭代相同的 object 时删除密钥。

>>> c = b.copy()
>>> id(b) == id(c)
False
>>> c[5] = 50
>>> c
{1: 10, 2: 20, 4: 40, 5: 50}
>>> 
>>> b
{1: 10, 2: 20, 4: 40}
>>> 

另一种方法是使用for i in list(g.nodes)

您的问题是由于 networkx 将图形存储在基于字典的数据结构中。

当你执行一个 for 循环来遍历字典时,如果字典本身发生变化,python 将遇到麻烦。

所以你需要做的是以某种方式创建一个列表或其他一些没有该属性的节点集合,然后删除它们。

如果您对“列表推导”还不满意,您可以这样做:

nodes_to_delete = []
for node in g.nodes:
    if 'commu_per' not in g.nodes[node]:
    nodes_to_delete.append(node)
g.remove_nodes_from(nodes_to_delete)

要使用列表理解(消除 for 循环)来做到这一点,您可以这样做

nodes_to_delete = [node for node in g.nodes if 'commu_per' not in g.nodes[node]]
g.remove_nodes_from(nodes_to_delete)
delete = [i for i in g.nodes if 'commu_per' not in g.nodes[node]]
g.remove_nodes_from(delete)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM