循环中使用Pickle仅存储单个值的原因排查
问题:使用Pickle存储图节点属性后仅保留单个整数的原因
我尝试使用Pickle存储特定数据以便后续轻松检索,代码如下:
import pickle import networkx as nx import pandas as pd import numpy as np import load_data as load # load the graph g = load.local_data() for node in g.nodes(): # get node degree pickle.dump(g.degree(node), open("./pickles/degree.pickle", "wb")) # get in-degree of node pickle.dump(g.in_degree(node), open("./pickles/indegrees.pickle", "wb")) # get out-degree of node pickle.dump(g.out_degree(node), open("./pickles/outdegrees.pickle", "wb")) # get clustering coefficients of node pickle.dump(nx.clustering(g, node), open("./pickles/clustering.pickle", "wb"))
打印相关命令时能输出所有节点及其属性,但打开Pickle文件后发现仅存储了单个整数,请问这是什么原因?
原因与解决方案
核心原因
你的代码在循环遍历每个节点时,每次都用wb模式打开文件并写入单个节点的属性值。wb模式是「写入二进制文件」,会直接清空文件原有内容再写入新数据。循环执行完毕后,每个Pickle文件里只会保留最后一个节点的属性值,也就是你看到的单个整数。
正确的实现方式
应该先把所有节点的对应属性收集到字典(或其他可序列化结构)中,再一次性写入Pickle文件,避免覆盖。
方案1:将所有属性存入一个字典后统一存储
import pickle import networkx as nx import load_data as load # 加载图数据 g = load.local_data() # 初始化字典存储所有节点的各类属性 all_node_attrs = { "degree": {}, "in_degree": {}, "out_degree": {}, "clustering": {} } # 遍历节点,批量收集属性 for node in g.nodes(): all_node_attrs["degree"][node] = g.degree(node) all_node_attrs["in_degree"][node] = g.in_degree(node) all_node_attrs["out_degree"][node] = g.out_degree(node) all_node_attrs["clustering"][node] = nx.clustering(g, node) # 一次性写入所有数据 pickle.dump(all_node_attrs, open("./pickles/all_node_attributes.pickle", "wb"))
方案2:按属性类型分别存储为独立文件
如果你需要每个属性单独存一个Pickle文件,可以先收集对应属性的完整字典再写入:
import pickle import networkx as nx import load_data as load g = load.local_data() # 批量生成各属性的字典 degrees = {node: g.degree(node) for node in g.nodes()} in_degrees = {node: g.in_degree(node) for node in g.nodes()} out_degrees = {node: g.out_degree(node) for node in g.nodes()} clusterings = {node: nx.clustering(g, node) for node in g.nodes()} # 分别写入对应文件 pickle.dump(degrees, open("./pickles/degree.pickle", "wb")) pickle.dump(in_degrees, open("./pickles/indegrees.pickle", "wb")) pickle.dump(out_degrees, open("./pickles/outdegrees.pickle", "wb")) pickle.dump(clusterings, open("./pickles/clustering.pickle", "wb"))
这样处理后,每个Pickle文件会包含所有节点的对应属性,而不是单个值。
内容的提问来源于stack exchange,提问作者sppokky
相关产品推荐
相关产品推荐

