将具有属性和边的节点从DataFrame加载到NetworkX

2024-09-29 02:24:14 发布

您现在位置:Python中文网/ 问答频道 /正文

我是使用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. 我应该只创建一个包含数据帧中节点信息的图,然后添加(附加)其他数据帧的边吗?如果是这样,并且由于nx.from_pandas_dataframe()需要有关边的信息,我想我不应该使用它来创建节点。。。我应该把这些信息作为单子传递吗?

  2. 我是否应该只创建一个带有数据帧边缘信息的图,然后将来自其他数据帧的信息作为属性添加到每个节点?有没有比遍历数据帧和节点更好的方法呢?


Tags: 数据方法networkx信息id图形节点步骤
3条回答

这里基本上是相同的答案,但是更新了一些细节。我们将从基本相同的设置开始,但这里不会有节点的索引,只是地址@LancelotHolmes comment并使其更通用的名称:

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 dataframe的索引设置为name属性,然后再将其设置为字典,以便NetworkX 2.x可以将其作为节点属性加载。

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

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

一句话:

from_pandas_dataframe在nx 2中不起作用,指的是这个

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

我认为在NX2.0中它是这样的:

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

使用^{}从边表创建加权图:

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')

然后使用^{}从字典中添加节点属性:

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.0开始,nx.set_node_attributes的参数顺序为changed(G, values, name=None)

使用上面的示例:

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

相关问题 更多 >