【问题标题】:create igraph Graph from pandas dataframe从 pandas 数据框创建 igraph Graph
【发布时间】:2021-08-14 20:48:10
【问题描述】:

我有以下 pandas 数据框包含如下边缘列表:

        name1              name2    weight
0  $hort, Too  Alexander, Khandi  0.083333
1  $hort, Too             B-Real  0.083333

我想从 pandas 数据框(而不是文件)创建一个 igraph 对象。 该图太大,因此我无法将其转换为邻接矩阵。该怎么做?

【问题讨论】:

    标签: python pandas igraph


    【解决方案1】:

    我还在 igraph 中寻找 Networkx from_pandas_dataframe 的等效函数,我发现使用 Graph.TupleList() 作为最佳解决方案。 所以基本上你从 3 个 pandas 列创建一个元组,然后使用这个函数来创建网络。

    tuples = [tuple(x) for x in df.values]
    Gm = igraph.Graph.TupleList(tuples, directed = True, edge_attrs = ['weight'])
    

    【讨论】:

    • 在这种情况下,igraph 分配的顶点编号如何与数据框中的原始名称相对应?
    • 每个顶点都将被赋予一个名为name的属性,该属性对应于DataFrame中的原始名称,即name1name2。您可以使用{v['name']: v.index for v in list(Gm.vs)} 获取 igraph 顶点索引到名称的映射。
    【解决方案2】:

    igraph 需要元组,pandas 提供 .itertuples() 用于一对:

    (source, target, weight(optional))
    

    假设您的数据框名为“df”,您可以通过以下方式从 pandas 数据框获取具有权重的有向图对象:

    import pandas as pd
    import igraph as ig
    
    g = ig.Graph.TupleList(df.itertuples(index=False), directed=True, weights=True, edge_attrs="weight")
    

    根据https://igraph.org/python/doc/igraph.Graph-class.html#TupleList

    weights - 指定图表加权的替代方法。如果 您将权重设置为 true 并且未给出 edge_attrs,它将是 假设 edge_attrs 是 ["weight"] 并且 igraph 将解析第三个 将每个项目中的元素转换为边缘权重

    因此,在您的情况下,您不需要“edge_attrs=”,但我添加了它以防万一更通用的解决方案。

    【讨论】:

    • 很好的答案!我找了很久。一个更正:在 g = ig.Graph.TupleList(df.itertuples(index=False),directed=True, weights=True, edge_attrs="weight") 中放入 weights=False , not True 否则我会出错
    • 您遇到了哪个错误? kaggle 示例没有显示任何错误或设置 weight=False 的原因(当然,除非您的数据框中没有权重列)。
    【解决方案3】:

    我总是这样做的方式如下,尽管我经常重复边缘,这就是为什么我的权重容易改变(我假设你的 pandas 数据框名为 df):

    import igraph
    
    edgelist = []
    weights = []
    for i in df.index():
        edge = (df.ix[i, 'name1'], df.ix[i, 'name2'])
        if edge not in edgelist:
            edgelist.append(edge)
            weights.append(1)
        else:
            weights[edgelist.index(edge)] += 1
    
    G = Graph()
    G.add_edges(edgelist)
    G.es['weight'] = weights
    

    【讨论】:

    • 你应该把括号放在“for i in df.index():”这一行中
    【解决方案4】:

    只是草图/伪代码,但是呢:

    for i, row in df.iterrows():
        graph.add_edge(row.name1, row.name2, weight=row.weight)
    

    【讨论】:

    • 当我使用这个代码时,我得到这个错误:AttributeError: 'tuple' object has no attribute 'node1'
    • @EmmaNej 感谢您的提醒。看起来像是从iterrows 返回了一个元组,因此您需要拆分该元组。一种方法是在 for 循环中指定索引和行对象。我更新了答案中的示例以反映这一点。
    • 是的,我也试过了,但仍然出错! TypeError: unbound method add_edge() 必须使用 Graph 实例作为第一个参数调用(改为使用 int64 实例)
    • 好的,这是一个新错误,所以看起来 igraph 有不同的 add_edge 实现。所以我会查找有关graph.add_edge() 工作原理的文档。我会看这个教程:igraph.org/python/doc/tutorial/tutorial.html 可能想尝试类似g.add_edges((2,0)) 的东西,其中20 是 from 和 to 值的 id。
    【解决方案5】:

    我使用的是 igraph 0.9.6 版,似乎有一种直接的方法可以做到这一点:

    import igraph as ig
    import pandas as pd
    
    mydata = pd.DataFrame({'name1': ['$hort, Too', '$hort, Too'], 
                       'name2': ['Alexander, Khandi', 'B-Real'], 
                       'weight': [0.083333, 0.083333]})
    mygraph = ig.Graph.DataFrame(mydata)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-07-03
      • 2016-05-17
      • 2018-03-02
      • 2018-11-13
      • 1970-01-01
      • 1970-01-01
      • 2021-12-02
      • 1970-01-01
      相关资源
      最近更新 更多