【问题标题】:Load nodes with attributes and edges from DataFrame to NetworkX将具有属性和边的节点从 DataFrame 加载到 NetworkX
【发布时间】:2017-03-02 14:31:42
【问题描述】:

我是使用 Python 处理图表的新手:NetworkX。到目前为止,我一直在使用 Gephi。那里的标准步骤(但不是唯一可能的)是:

  1. 从表格/电子表格中加载节点信息;其中一列应该是 ID,其余是关于节点的元数据(节点是人,所以性别,组......通常用于着色)。喜欢:

    id;NormalizedName;Gender
    per1;Jesús;male
    per2;Abraham;male
    per3;Isaac;male
    per4;Jacob;male
    per5;Judá;male
    per6;Tamar;female
    ...
    
  2. 然后也从表格/电子表格中加载边,使用与节点电子表格的列 ID 中相同的节点名称,通常有四列(目标、源、权重和类型):

    Target;Source;Weight;Type
    per1;per2;3;Undirected
    per3;per4;2;Undirected
    ...
    

这是我拥有的两个数据框,我想在 Python 中加载它们。阅读有关 NetworkX 的信息,似乎不太可能将两个表(一个用于节点,一个用于边)加载到同一个图中,我不确定最好的方法是什么:

  1. 我是否应该只使用来自 DataFrame 的节点信息创建一个图,然后添加(附加)来自另一个 DataFrame 的边?如果是这样,并且由于 nx.from_pandas_dataframe() 需要有关边缘的信息,我想我不应该使用它来创建节点...我应该将信息作为列表传递吗?

  2. 我是否应该只使用来自 DataFrame 的边信息创建一个图,然后将来自另一个 DataFrame 的信息作为属性添加到每个节点?有没有比遍历 DataFrame 和节点更好的方法?

【问题讨论】:

    标签: python pandas graph networkx


    【解决方案1】:

    使用nx.from_pandas_dataframe从边表创建加权图:

    import networkx as nx
    import pandas as pd
    
    edges = pd.DataFrame({'source' : [0, 1],
                          'target' : [1, 2],
                          'weight' : [100, 50]})
    
    nodes = pd.DataFrame({'node' : [0, 1, 2],
                          'name' : ['Foo', 'Bar', 'Baz'],
                          'gender' : ['M', 'F', 'M']})
    
    G = nx.from_pandas_dataframe(edges, 'source', 'target', 'weight')
    

    然后使用set_node_attributes从字典中添加节点属性:

    nx.set_node_attributes(G, 'name', pd.Series(nodes.name, index=nodes.node).to_dict())
    nx.set_node_attributes(G, 'gender', pd.Series(nodes.gender, index=nodes.node).to_dict())
    

    或者遍历图来添加节点属性:

    for i in sorted(G.nodes()):
        G.node[i]['name'] = nodes.name[i]
        G.node[i]['gender'] = nodes.gender[i]
    

    更新:

    截至nx 2.0nx.set_node_attributes 的参数顺序为changed(G, values, name=None)

    使用上面的例子:

    nx.set_node_attributes(G, pd.Series(nodes.gender, index=nodes.node).to_dict(), 'gender')
    

    截至nx 2.4G.node[] is replaced by G.nodes[]

    【讨论】:

    • 太棒了,谢谢!我的节点列表还包括一些有时我不需要的节点,所以我首先从边缘列出所有节点名称并使用以下信息过滤节点表:entities_edges = sorted(list(set(edges["Target"].tolist()+edges["Source"].tolist()))); nodes = pd.read_csv(input_folder+file_nodes, encoding="utf-8", sep="\t"); nodes = nodes[nodes['id'].isin(entities_edges)]; 然后我已经按照你说的做了。你怎么看待这件事?非常感谢您的回答!!!
    • 乍一看似乎是正确的。您可以稍后在 Gephi 中过滤它们,因为它们的度数为零
    • 如果对set_node_attributes使用字典方式,则无需担心entities_edges中不包含的节点。随后可以使用G.remove_nodes_from(nx.isolates(G)) 从图中删除未连接的节点。
    • @h_s ,很好的答案,但我想知道我是否没有有意义的索引如何使用nx.set_node_attributes 方法,或者我只能使用 for 循环?
    • 遗憾的是,NetworkX 2.3 没有from_pandas_dataframe
    【解决方案2】:

    这里的答案基本相同,但更新了一些细节。我们将从基本相同的设置开始,但这里不会有节点的索引,只是用于解决 @LancelotHolmes 评论的名称并使其更多一般:

    import networkx as nx
    import pandas as pd
    
    linkData = pd.DataFrame({'source' : ['Amy', 'Bob'],
                      'target' : ['Bob', 'Cindy'],
                      'weight' : [100, 50]})
    
    nodeData = pd.DataFrame({'name' : ['Amy', 'Bob', 'Cindy'],
                      'type' : ['Foo', 'Bar', 'Baz'],
                      'gender' : ['M', 'F', 'M']})
    
    G = nx.from_pandas_edgelist(linkData, 'source', 'target', True, nx.DiGraph())
    

    这里的True 参数告诉NetworkX 将linkData 中的所有属性保留为链接属性。在这种情况下,我将其设为 DiGraph 类型,但如果您不需要它,那么您可以通过显而易见的方式将其设为另一种类型。

    现在,由于您需要通过从 linkData 生成的节点的名称来匹配 nodeData,因此您需要将 nodeData 数据帧的索引设置为 name 属性,然后再将其设置为字典,以便 NetworkX 2 .x 可以将其作为节点属性加载。

    nx.set_node_attributes(G, nodeData.set_index('name').to_dict('index'))
    

    这会将整个 nodeData 数据帧加载到一个字典中,其中键是名称,其他属性是该键中的键:值对(即,节点索引是其名称的普通节点属性)。

    【讨论】:

      【解决方案3】:

      一个小小的说明:

      from_pandas_dataframe 在 nx 2 中不起作用,参考这个

      G = nx.from_pandas_dataframe(edges, 'source', 'target', 'weight')
      

      我认为在 nx 2.0 中是这样的:

      G = nx.from_pandas_edgelist(edges, source = "Source", target = "Target")
      

      【讨论】:

        猜你喜欢
        • 2019-11-16
        • 2016-05-04
        • 1970-01-01
        • 2013-03-18
        • 1970-01-01
        • 2012-03-27
        • 1970-01-01
        • 1970-01-01
        • 2023-04-09
        相关资源
        最近更新 更多