2012-06-14 53 views
8

我想要处理一个具有数亿个节点的超大型NetworkX图形对象。我希望能够将它写入文件,以便不消耗我所有的计算机内存。但是,我需要不断搜索现有节点,更新边缘等。读/写NetworkX图形对象

有没有一个很好的解决方案?我不知道它将如何与所提供的任何关于http://networkx.lanl.gov/reference/readwrite.html

唯一的解决方案,我能想到的是给每个节点存储与在文件系统中的其他节点引用一个单独的文件中的文件格式的工作 - 这样,打开一个节点进行检查不会使存储器过载。是否有大量数据的现有文件系统(例如PyTables)在不编写自己的样板代码的情况下执行此操作?

回答

2

如果你已经建立了这个作为NetworkX图,然后将已经在内存中。对于这个庞大的图表,我猜测你必须做一些类似于你对单独文件的建议。但是,我没有使用单独的文件,而是使用数据库来存储每个节点之间的多对多连接。换句话说,你需要一个节点表和一个边缘表,然后查询一个特定节点的邻居,你可以查询任何一边有特定节点的边。这应该很快,但我不确定您是否能够利用NetworkX的分析功能,而无需先在内存中构建整个网络。

+0

感谢Luis。Essentially我存储在一个数据库中,但是,查询节点来获取邻居是非常昂贵的,我只能想象Google的服务器是什么样的... – ejang

+0

如果图形已经在RAM中,那么为什么要序列化它是一个问题?磁盘空间比RAM便宜)或者NetworkX有某种内部方法来压缩表示,并且在序列化过程中会弹出?我很好奇 – user

+0

我认为这个问题并没有把重点放在序列化上,而是把它保存在一个结构中这将允许有效的查询。这是我对数据库的建议来自何处。 – LuisZaman

18

第一次尝试pickle;它旨在序列化任意对象。

创建DiGraph和序列化到一个文件的一个例子:

import pickle 
import networkx as nx 

dg = nx.DiGraph() 
dg.add_edge('a','b') 
dg.add_edge('a','c') 
pickle.dump(dg, open('/tmp/graph.txt', 'w')) 

从文件加载一个DiGraph的一个例子:

import pickle 
import networkx as nx 

dg = pickle.load(open('/tmp/graph.txt')) 
print dg.edges() 

输出:

[('a', 'c'), ('a', 'b')] 

如果这是不够高效的,我会写你自己的例程序列化:

  1. 边缘和
  2. 节点(如果一个节点是入射到无毛边)。

请注意,尽可能使用列表推导可能会更有效率(而不是标准的循环)。

如果是不是足够有效的,我会打电话给一个C++程序从内部的Python: http://docs.python.org/extending/extending.html

+2

+1泡菜是一件好事,以前从未听说过,谢谢! – Eduardo

+1

Pickle为对象生成MASSIVE文件,如果这已经是一个大型网络,pickle几乎肯定不会起作用。由于许多其他原因,这是一个很好的和未被充分利用的软件包! – LuisZaman

+0

@LuisZaman我知道你的意思。在那种情况下,我会手动序列化边和节点(如上所述)。但是如果图形已经在RAM中,那么如果泡菜膨胀得不适合磁盘,我会感到非常惊讶。 – user