如何解决从图中删除没有特定属性的节点时出错
我用 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,4: 40}
>>>
使用 copy() 方法获取新副本,以便您可以在迭代同一对象时删除键。
>>> c = b.copy()
>>> id(b) == id(c)
False
>>> c[5] = 50
>>> c
{1: 10,4: 40,5: 50}
>>>
>>> b
{1: 10,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)
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。