【问题标题】:MemoryError while counting edges in graph using Networkx使用 Networkx 计算图中的边时出现 MemoryError
【发布时间】:2017-06-10 10:53:36
【问题描述】:

我最初的目标是使用 Networkx 进行一些结构特性分析(直径、聚类系数等)。但是,我只是试图计算给定图中存在多少条边,我已经绊倒了。该图可在from over here (beware: 126 MB zip file) 下载,由 1,632,803 个节点和 30,622,564 条边组成。 请注意,如果您要下载此文件,请务必从其中删除位于文件顶部的 cmets(包括 #)

我的机器中有 8 GB 内存。对于这种大小的图表,我的计划(直径/聚类系数)是否过于雄心勃勃?我希望不会,因为我喜欢 networkx,因为它很简单,而且看起来很完整。但是如果它雄心勃勃,您能否建议我可以使用另一个库来完成这项工作?

import networkx as nx

graph = nx.Graph()
graph.to_directed()

def create_undirected_graph_from_file(path, graph):
    for line in open(path):
        edges = line.rstrip().split()
        graph.add_edge(edges[0], edges[1])

print(create_undirected_graph_from_file("C:\\Users\\USER\\Desktop\\soc-pokec-relationships.txt", graph).g.number_of_edges())

错误:

Traceback (most recent call last):
  File "C:/Users/USER/PycharmProjects/untitled/main.py", line 12, in <module>
    print(create_undirected_graph_from_file("C:\\Users\\USER\\Desktop\\soc-pokec-relationships.txt", graph).g.number_of_edges())
  File "C:/Users/User/PycharmProjects/untitled/main.py", line 8, in create_undirected_graph_from_file
    edges = line.rstrip().split()
MemoryError

【问题讨论】:

  • 不是您要求的,但您可以尝试通过切换到 SNAP(您的数据集来自项目的 C++ 系统)来增加您可以处理的网络的大小。他们提供 Python 绑定,可用here。不幸的是,它似乎只适用于 Python 2.7...
  • 感谢您的提示!事实上,我看到 SNAP 有 python 绑定。我还没有尝试过(因为我认为 networkx 更容易使用)。我会尝试一下,看看那里是否工作正常。谢谢!如果那里不可能,我认为唯一的解决方案是增加内存大小。虽然不知道内存有限是否还有其他可能
  • @alexis,我可以使用 SNAP Pyton 库计算多达 1.17 亿条边!在性能方面似乎也好得多。让我想知道 networkx 是如何只为 3000 万条边使用这么多内存的。谢谢 - 编辑:实际上很明显,因为 snap 在下面使用 C/C++,而 networkx 是纯粹的 python。
  • 没错,这就是我建议它的原因。也就是说,networkx 可以在幕后使用了高性能数据结构(例如 numpy 数组)。但它似乎在大多数情况下通过使用普通的 dicts 来实现它的灵活性。

标签: python graph networkx


【解决方案1】:

一个潜在的问题是字符串占用大量内存。由于所有边都是整数,因此您可以通过在创建边之前将它们转换为整数来受益。您将受益于更快的内部跟踪,并且内存占用更少!具体来说:

def create_undirected_graph_from_file(path, graph):
    for line in open(path):
        a, b = line.rstrip().split()
        graph.add_edge(int(a), int(b))
    return graph

我还建议您更改您的 open 以使用上下文并确保文件被打开:

def create_undirected_graph_from_file(path, graph):
    with open(path) as f:
        for line in f:
            a, b = line.rstrip().split()
            graph.add_edge(int(a), int(b))
    return graph

或者神奇的单线:

def create_undirected_graph_from_file(path, graph):
    with open(path) as f:
        [graph.add_edge(*(int(point) for point in line.rstrip().split())) for line in f]
    return graph

还有一点要记住。 Graph.to_directed 返回一个新图表。因此,请务必将 graph 设置为 this 的结果,而不是丢弃结果。

【讨论】:

  • 即使使用这种方法,我仍然会得到 10GB 的内存峰值,所以这可能仍然是太多的数据。不过,我想,在内存有限的情况下,python 会更积极地进行垃圾收集。
  • 感谢 Eric 的帮助,我会在几个小时后查看是否有帮助!
  • 再次感谢埃里克。不幸的是,发生了同样的错误。我认为唯一的解决方案是增加 RAM。
猜你喜欢
  • 1970-01-01
  • 2013-06-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多