【问题标题】:What is the optimal way to create a graph with add_edge_list() method?使用 add_edge_list() 方法创建图形的最佳方法是什么?
【发布时间】:2019-09-26 04:18:59
【问题描述】:

我正在尝试通过graph-tool 库(接近 10^6 - 10^7 个顶点)创建大图,并用顶点名称填充顶点属性或使用名称而不是顶点索引。我有:

  1. 名字列表:

    ['50', '56', '568']
    
  2. 一组边,但不是顶点索引,而是由它们的名称组成:

    edge_list = {frozenset({'568', '56'}), frozenset({'56', '50'}), frozenset({'50', '568'})}
    

因为add_edge_list() 允许在图中没有这样的顶点时创建顶点。我正在尝试用它来填充一个空图。它工作正常,但是当我尝试通过其名称获取顶点时,我收到一个错误,即没有具有此类索引的顶点。

这是我的程序的代码:

g = grt.Graph(directed=False)
edge_list = {frozenset({'568', '56'}), frozenset({'56', '50'}), frozenset({'50', '568'})}
ids = ['50', '56', '568']
g.add_edge_list(edge_list, hashed=True, string_vals=True)
print(g.vertex('50'))

print(g.vertex('50'))的错误信息:

ValueError: Invalid vertex index: 50

我要创建图表:

  1. 仅使用edge_list
  2. 通过名称快速访问顶点;
  3. 按时间优化(如果可能,还有 RAM)。

有什么好的办法吗?

编辑: 当前代码:

g = grt.Graph(directed=False)
g.add_vertex(len(ids))
vprop = g.new_vertex_property("string", vals=ids)
g.vp.user_id = vprop  
for vert1, vert2 in edges_list:
    g.add_edge(g.vertex(ids_dict[vert1]), g.vertex(ids_dict[vert2]))

【问题讨论】:

    标签: python python-3.x graph networkx graph-tool


    【解决方案1】:

    如果你有一个包含 10^6 - 10^7 个顶点的密集图(它是一些医学数据还是社交图?它可以改变一切),你不应该使用networkx,因为它是用纯 Python 编写的,因此比 graph-tooligraph 慢约 10-100 倍。在您的情况下,我建议您使用graph-tool。它是最快的(~as igraph)Python 图形处理库。

    graph-tool 的行为不同于 networkx。当您创建networkx 节点时,它的标识符就是您在节点构造函数中编写的内容,因此您可以通过其ID 获取节点。在图形工具中,每个顶点 ID 都是从 1 到 GRAPH_SIZE 的整数:

    图中的每个顶点都有一个唯一的索引,它总是在 0 和 N−1 之间,其中 N 是顶点的数量。这个索引可以通过使用图的 vertex_index 属性(这是一个属性映射,参见属性映射),或者通过将顶点描述符转换为一个 int 来获得。

    关于图形、顶点或边的所有附加信息都存储在property maps 中。当您将.add_edge_list()hashed=True 一起使用时,新的属性映射将作为.add_edge_list() 的结果返回。所以在你的情况下,你应该像这样处理你的顶点:

    # Create graph
    g = grt.Graph(directed=False)
    
    # Create edge list
    # Why frozensets? You don't really need them. You can use ordinary sets or tuples
    edge_list = {
        frozenset({'568', '56'}),
        frozenset({'56', '50'}),
        frozenset({'50', '568'})
    }
    
    # Write returned PropertyMap to a variable!
    vertex_ids = g.add_edge_list(edge_list, hashed=True, string_vals=True)
    
    g.vertex(1)
    
    Out [...]: <Vertex object with index '1' at 0x7f3b5edde4b0>
    
    vertex_ids[1]
    
    Out [...]: '56'
    

    如果要根据ID获取一个顶点,应该手动构造映射dict(好吧,我不是graph-tool大师,但是我找不到简单的解决方案):

    very_important_mapping_dict = {vertex_ids[i]: i for i in range(g.num_vertices())}

    这样就可以很方便的得到一个顶点索引了:

    very_important_mapping_dict['568']
    
    Out [...]: 0
    
    vertex_ids[0]
    
    Out [...]: '568'
    

    【讨论】:

    • 是的,它实际上是一个社交图谱。它会有所帮助吗?我使用igraph 进行聚类(或搜索社区,如果您更喜欢这个术语),graph-tool 用于测量中心性和绘制图表。我正在使用 freezeset 从源收集数据。运行时是主要问题。问题是:什么会更快:在循环中使用add_edge_lis()add_edge()?我在上面的问题字段中添加了当前代码。
    猜你喜欢
    • 1970-01-01
    • 2018-06-07
    • 2017-08-06
    • 1970-01-01
    • 2022-01-05
    • 2017-04-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多