NetworkX节点属性保存异常问题咨询
NetworkX节点属性设置后校验失败的原因
从文件读取边列表创建NetworkX的DiGraph图,再从另一文件为部分节点添加date属性(边列表中部分节点无该属性)。设置属性时断言通过,但后续再次校验时,部分应存在date属性的节点断言失败。
代码如下:
import networkx as nx # Load edges G = nx.read_edgelist("edges.txt", nodetype=int, create_using=nx.DiGraph) # Verify load was right print("Number of nodes:", G.order()) print("Number of edges:", G.size()) print() num_dates = 0 num_useless = 0 with open("node-dates.txt") as f: for line in f: if line[0] == "#": continue nodeID = line.split()[0] if nodeID[:2]=="11": nodeID = int(nodeID[2:]) if int(nodeID) in G: num_dates += 1 else: num_useless += 1 G.add_node(int(nodeID)) G.nodes[int(nodeID)]["date"] = line.split()[1] # This below assert passes assert(G.nodes[int(nodeID)]["date"] == line.split()[1]) print("Number of nodes:", G.order()) print("Number of nodes with dates:", num_dates+num_useless) print("Number of nodes with dates and edges:", num_dates) print("Number of nodes with dates but no edges:", num_useless) print("Number of nodes with edges but no dates:", G.order()-num_dates-num_useless) count_failed_assert = 0 with open("node-dates.txt") as f: for line in f: if line[0] == "#": continue nodeID = line.split()[0] if nodeID[:2]=="11": nodeID = int(nodeID[2:]) try: # But this assert fails? assert(G.nodes[int(nodeID)]["date"] == line.split()[1]) except: count_failed_assert += 1 print(count_failed_assert)
运行输出:
Number of nodes: 34546 Number of edges: 421578 Number of nodes: 39951 Number of nodes with dates: 38557 Number of nodes with dates and edges: 33152 Number of nodes with dates but no edges: 5405 Number of nodes with edges but no dates: 1394 2446
原因分析
核心问题是**node-dates.txt文件中存在重复的节点ID记录**:
- 第一次遍历文件时,每处理一行就设置对应节点的
date属性,此时断言是拿当前行的date值和刚设置的属性对比,自然一致,所以断言通过。 - 如果同一个节点ID在文件中出现多次,后面的行会直接覆盖掉之前设置的
date属性值。 - 第二次遍历文件时,当遇到该节点ID的早期记录,用该行的
date值去对比节点现在的属性(已经被后续行覆盖),就会出现不相等的情况,导致断言失败,最终count_failed_assert的数值就是文件中重复节点ID的出现次数(减去首次出现的次数)。
你可以统计node-dates.txt中重复节点ID的数量,应该和输出的2446一致。
内容的提问来源于stack exchange,提问作者Anili
相关产品推荐
相关产品推荐

