【发布时间】:2016-08-10 18:22:37
【问题描述】:
我在 Python 中使用 networkx1.10 进行一个项目,该项目需要将网络转储到硬盘上,然后重新加载它们,以便继续执行一些操纵此类网络的算法。
我一直在尝试用几种不同的方式来做到这一点:首先使用 nx.write_gml() 和 nx_read_gml(),现在使用 pickle/cpickle。
虽然从表面上看一切正常,但我注意到无论保存/加载是否在某个时间点发生,我在模拟中都会得到不同的结果。
我认为这可能与某些网络似乎被转储/重新加载过程修改的事实有关(这当然是出乎意料的)。
为了调试,现在我正在使用 pickle 保存和重新加载每个网络,比较转储/重新加载前后它们的 gml 表示(通过 nx.write_gml / nx.generate_gml 实现)。这样做,我注意到了一些差异。
在某些情况下,只是某些图形属性的顺序被修改,不会对我的程序造成任何伤害。在其他情况下,两条边在 gml 表示中出现的顺序是不同的,同样没有害处。
但是,通常会修改某些节点的 ID,如下例所示:
https://www.diffchecker.com/zvzxrshy
虽然边缘似乎进行了相应的修改,因此网络看起来是等效的,但 ID 的这种变化可能会改变我的模拟(原因我不打算解释)。
我相信这可能是我问题的根源。
您知道为什么会发生这种情况吗,即使使用低级序列化机制(例如由 pickle/cpickle 实现的那些机制)?
如何确保序列化过程前后的网络完全相同?
我正在做这样的事情:
with open('my_network.pickle', 'wb') as handle:
pickle.dump(my_network, handle, protocol=pickle.HIGHEST_PROTOCOL)
...
with open('my_network.pickle', 'rb') as handle:
my_network_reloaded = pickle.load(handle)
# compare nx.write_gml for my_network and my_network_reloaded
任何帮助将不胜感激:过去三天我一直在与这个问题作斗争,我快疯了!
谢谢
【问题讨论】:
-
我无法从文档中真正看出,但使用 Python 的
pickle和write_gpickle和read_gpickle(description) 有什么区别吗? -
我在使用这两种方法时遇到了问题...
-
你的问题的症结是“(原因我不打算解释)”。如果您确实需要生成具有特定 id 和排序的 gml 格式输出,则需要修改现有编写器或编写一些自定义软件来执行此操作。您可以使用 id 以外的其他属性来标记您的节点吗? (对于 gml 格式,那些需要是整数并自动生成以确保)。
-
@Aric 我认为在序列化网络时节点 ID 的这些变化可能是我问题的根源,因为我的算法确实以可能对这些变化敏感的方式操纵网络。有时我会像这样随机选择节点(和边):random.choice(G.nodes()),并在该节点/边上执行一些操作(例如修改属性、删除节点、添加边等.)。我担心如果节点的 ordering/id 发生变化,我最终可能会选择不同的节点而不是我会选择的节点,因此,我会改变整体结果。
标签: python serialization pickle networkx gml