我正在尝试处理具有数亿节点的超大型NetworkX Graph对象。我希望能够将其写入文件,以免占用我的所有计算机内存。但是,我需要不断搜索现有节点,更新边缘等。
这有一个很好的解决方案吗?我不确定它如何与http://networkx.lanl.gov/reference/readwrite.html
上提供的任何文件格式一起使用我能想到的唯一解决方案是将每个节点存储为一个单独的文件,并引用文件系统中的其他节点 - 这样,打开一个节点进行检查不会使内存过载。是否存在大量数据的现有文件系统(例如PyTables),而无需编写我自己的样板代码?
答案 0 :(得分: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')]
如果这不够有效,我会编写自己的例程来序列化:
请注意,尽可能使用列表推导可能会更有效(而不是循环的标准)。
如果这个效率不高,我会在Python中调用C ++例程: http://docs.python.org/extending/extending.html
答案 1 :(得分:2)
如果您已将其构建为NetworkX图形,那么它已经在内存中。对于这个庞大的图表,我的猜测是你必须做类似你用单独文件建议的东西。但是,我不是使用单独的文件,而是使用数据库来存储节点之间的多对多连接。换句话说,你有一个节点表和一个边表,然后查询特定节点的邻居,你可以查询任何一端有特定节点的边。这应该很快,但我不确定你是否能够在没有首先在内存中构建整个网络的情况下利用NetworkX的分析功能。
答案 2 :(得分:0)
我忘了最初来StackOverflow来解决什么问题,但是我偶然发现了这个问题,并且(近十年来太晚了!)可以推荐Grand,这是我们为解决此问题而编写的类似于networkx的库:
之前
import networkx as nx
g = nx.DiGraph()
g.add_edge("A", "B")
print(len(g.edges()))
之后
import grand
from grand.backends import SQLBackend # or choose another!
g = grand.Graph(backend=SQLBackend())
g.nx.add_edge("A", "B")
print(len(g.nx.edges()))
API与NetworkX相同,但是数据存在于SQL,DynamoDB等中。