【发布时间】:2018-06-28 14:24:12
【问题描述】:
我有一个 3.7 GB 的边列表文件,它描述了 20k 个节点上的完整图,其中每条边都有一个浮点数 'weight'(全为 1.0)和一个整数 'length'(全为 0-1000)。
所以edgelist文件的头部是这样的:
0 1 1.0 76
0 2 1.0 85
0 3 1.0 118
0 4 1.0 94
0 5 1.0 71
...
我正在使用:
def load_graph(file_path: str) -> Graph:
return read_edgelist(file_path, nodetype=int,
data=[('weight', float),
('length', int)])
但是,当networkx.read_edgelist 运行时,我的计算机因内存使用量接近 100 GB 而停止运行。
什么给了?这是read_edgelist 特有的,还是networkx.Graph 只是
使用大量内存?无论哪种方式,任何人都可以推荐一个占用空间更小的替代图形库吗?
【问题讨论】:
-
有什么理由需要它作为图表吗?
D[(0,1)] = (1.0,76)将是一种更有效的方式来存储边缘。由于它是一个完整的图,我不清楚将其实际存储为图而不是仅将其存储为每个边的条目的字典有多大优势。 -
图表给我的好处是边是无向的。所以 (0,1) 与 (1,0) 相同。有没有办法使用元组(或类似的东西)作为字典键,但不关心它们的条目顺序?这将允许我放弃 networkx。
-
好的,这个问题的答案stackoverflow.com/q/41259493/2883198 说使用
frozensets 作为键,所以我会试试看。 -
另一种方法是有一个 getter 函数,它总是按索引的顺序检查元组键(
frozenset有一些开销,对于这个数据大小,值得优化)。此外,对于处理来说,使用内存更紧凑的存储对我来说是有意义的——例如NumPy数组。 -
@sophros 感谢您的评论,但我并没有完全理解——您能再明确一点吗? freezeset 的开销是多少,我该如何解决?一个numpy数组会比一个frozenset-keyed dict的namedtuples(这是我现在使用的)更有效吗?我应该清楚该图表“几乎”完整,但我不能依赖这个事实,例如获取事件边的列表。现在我使用理解
n->set(e for e in self.edges if n in edge)其中self.edges是我提到的字典。我会问一个新的 SO 问题,但我不确定要问什么!
标签: python-3.x memory networkx