我需要能够在python中操作一个大的(10 ^ 7个节点)图形。对应于每个节点/边缘的数据是最小的,例如,少量的字符串。在 内存和速度 方面,最有效的方法是什么?
dicts的词典更灵活,更易于实现,但我直观地期望列表列表更快。 list选项还要求我将数据与结构分开,而dicts允许这样的东西:
graph[I][J]["Property"]="value"
你会建议什么?
是的,我应该对效率更清楚一点。在这种特殊情况下,我的意思是随机访问检索。
将数据加载到内存中不是一个大问题。这是一劳永逸的。耗时的部分是访问节点,因此我可以提取信息并测量我感兴趣的指标。
我没有考虑过让每个节点成为一个类(所有节点的属性都相同),但似乎会增加一层额外的开销?我希望有人可以直接体验他们可以分享的类似案例。毕竟,图形是CS中最常见的抽象之一。
答案 0 :(得分:53)
我强烈建议你看看NetworkX。它是经过实战考验的战马,是大多数“研究”类型在他们需要对基于网络的数据进行分析时所能达到的第一个工具。我已经在笔记本上操作了数百个边缘的图形而没有问题。它功能丰富,非常易于使用。你会发现自己更多地关注手头的问题,而不是底层实现的细节。
Erdős-Rényi随机图生成和分析的示例
"""
Create an G{n,m} random graph with n nodes and m edges
and report some properties.
This graph is sometimes called the Erd##[m~Qs-Rényi graph
but is different from G{n,p} or binomial_graph which is also
sometimes called the Erd##[m~Qs-Rényi graph.
"""
__author__ = """Aric Hagberg (hagberg@lanl.gov)"""
__credits__ = """"""
# Copyright (C) 2004-2006 by
# Aric Hagberg
# Dan Schult
# Pieter Swart
# Distributed under the terms of the GNU Lesser General Public License
# http://www.gnu.org/copyleft/lesser.html
from networkx import *
import sys
n=10 # 10 nodes
m=20 # 20 edges
G=gnm_random_graph(n,m)
# some properties
print "node degree clustering"
for v in nodes(G):
print v,degree(G,v),clustering(G,v)
# print the adjacency list to terminal
write_adjlist(G,sys.stdout)
可视化也很简单:
更多可视化:http://jonschull.blogspot.com/2008/08/graph-visualization.html
答案 1 :(得分:13)
即使这个问题现在已经很老了,我认为值得一提的是我自己的用于图形操作的python模块graph-tool。它非常有效,因为数据结构和算法是用C ++实现的,使用Boost Graph Library进行模板元编程。因此,它的性能(内存使用和运行时)与纯C ++库相当,并且可以比典型的python代码好几个数量级,而不会牺牲易用性。我经常使用它来处理非常大的图形。
答案 2 :(得分:6)
如前所述,NetworkX非常好,另一个选项是igraph。这两个模块将拥有您可能需要的大多数(如果不是全部)分析工具,并且这两个库通常与大型网络一起使用。
答案 3 :(得分:4)
字典也可能包含开销,具体取决于实际实现。哈希表通常包含一些可用节点的素数,即使您可能只使用几个节点。
根据你的例子“财产”判断,你是否会更好地使用最终级别和真实属性的类方法?或者属性的名称是否在节点之间发生了很大变化?
我会说“有效”意味着什么取决于很多事情,例如:
我认为你会发现一个快速的数据结构通常比一个慢的数据结构消耗更多的内存。情况并非总是如此,但大多数数据结构似乎都遵循这一点。
字典可能很容易使用,并且为您提供相对统一的快速访问,它很可能会使用比您建议的列表更多的内存。但是,列表在向其中插入数据时通常会包含更多开销,除非它们预先分配X节点,否则它们将再次使用更多内存。
总的来说,我的建议是只使用对您来说最自然的方法,然后对系统进行“压力测试”,向其中添加大量数据并查看它是否成为问题您可能还考虑在系统中添加一个抽象层,这样如果您以后需要更改内部数据结构,则无需更改编程接口。
答案 4 :(得分:3)
据我了解,随机访问对于Python的dicts和列表都是恒定的时间,区别在于你只能随机访问带有列表的整数索引。我假设您需要按标签查找节点,因此您需要一个dicts的字典。
但是,在性能方面,将其加载到内存中可能不是问题,但是如果你使用太多,你最终会交换到磁盘,这将破坏Python的高效dicts的性能。尽量减少内存使用量。此外,RAM现在非常便宜;如果你做了很多这样的事情,没有理由不至少有4GB。
如果您希望了解如何降低内存使用率,请提供有关您为每个节点跟踪的信息类型的更多信息。
答案 5 :(得分:2)
创建基于类的结构可能比基于dict的结构有更多的开销,因为在python类中实际使用dicts。
答案 6 :(得分:1)
毫无疑问,对于图形来说,NetworkX是迄今为止最好的数据结构。它附带辅助函数,数据结构和算法,随机序列生成器,装饰器,Cuthill-Mckee排序,上下文管理器等实用程序
NetworkX非常棒,因为它可以用于图形,有向图和多图形。它可以用多种方式编写图形:邻接列表,多线邻接列表, 边缘列表,GEXF,GML。它适用于Pickle,GraphML,JSON,SparseGraph6等。
它具有各种radimade算法,包括: 近似,二分,边界,中心性,Clique,聚类,着色,组件,连通性,循环,有向无环图, 距离测度,支配集,欧拉,同构,链接分析,链接预测,匹配,最小生成树,富俱乐部,最短路径,遍历,树。