我有一个3.7 GB的边缘列表文件,它描述了2万个节点上的完整图形,其中每个边缘都有一个浮点数'weight'
(全部为1.0)和一个整数'length'
(全部为0–1000)。
因此边列表文件的头看起来像这样:
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
只是
使用大量的内存?不管哪种方式,谁能推荐一个替代的图形库,它以较小的占用空间运行?
答案 0 :(得分:1)
鉴于讨论从networkx
的性能转移到存储“几乎”完整图的最佳方式,我将集中在总结背后的基本原理,而不是使用元组而不是frozenset
类型暂时的关键。
我试图对此进行确认,但是给定更多的方法frozenset
会比元组占用更多的内存。从this question中,我了解到哈希算法已被重新实现,这有助于执行字典插入和查找(途中需要对键进行哈希处理),但另一方面,Python已针对元组,列表和字符串进行了优化。这么长的长度,这使我想知道是否仅由于这个原因2元组仍不比frozenset
快?
现在,当我们考虑NumPy
数组时,它们可能会更好地完成任务的原因是多种多样的:
NumPy
对于更大规模的数据(例如成千上万个值),比普通列表更理想。在您的情况下,您似乎需要存储2个值-一个float
,一个int
。您可以分配2个2-dim ndarray
-一种int
和一种float32
类型。您可以对角填充数组并创建一个特殊的访问器方法(将检查两个索引的顺序,这可能会更慢),也可以填充两个索引(例如:1,2和2,1)。
我假设您并非一直都需要两个值,因此将int
和float32
值去耦实际上对于使用各个值的算法性能是有益的。 ndarray
所消耗的内存应该较小,并且索引的连续处理要比字典在内存中随机跳动的情况要快得多。