13

我正在尝试处理具有数亿个节点的超大规模 NetworkX Graph 对象。我希望能够将其写入文件,以免占用我所有的计算机内存。但是,我需要不断地搜索现有节点、更新边缘等。

有没有好的解决方案?我不确定它如何与http://networkx.lanl.gov/reference/readwrite.html上提供的任何文件格式一起使用

我能想到的唯一解决方案是将每个节点存储为一个单独的文件,并引用文件系统中的其他节点 - 这样,打开一个节点进行检查不会使内存过载。是否有用于大量数据(例如 PyTables)的现有文件系统来执行此操作而无需编写我自己的样板代码?

4

3 回答 3

24

第一次尝试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. 节点(如果节点不与边相连)。

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

如果不够有效,我会从 Python 中调用 C++ 例程:http: //docs.python.org/extending/extending.html

于 2012-07-06T01:26:46.147 回答
4

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

于 2012-08-06T20:10:54.523 回答
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 等中。

于 2020-11-20T02:54:14.607 回答