Python:如何使用与另一个数据框相对应的networkx创建图?

时间:2018-07-22 13:39:22

标签: python pandas dataframe networkx

我有两个数据框dfdf1df包含一些节点的信息。所以

df  Name       Age
0   Jack       33
1   Anna       25
2   Emilie     49
3   Frank      19
4   John       42

df1包含两个人之间的联系数量信息。在df1中,我们可以有一些不在df中出现的人

df1    Name1    Name2   c
0      Frank    Paul    2
1      Julia    Anna    5
2      Frank    John    1
3      Emilie   Jack    3
4      Tom      Steven  2
5      Tom      Jack    5

我想用df中的节点和df1中的连接之间的信息创建一个邻接矩阵。

为了从df1创建邻接矩阵,我做了以下工作:

import networkx as nx
G = nx.Graph()
G = nx.from.pandas_dataframe(df1, 'Name1', 'Name2', ['c'])
adj = nx.adjacency_matrix(G)

但是,以这种方式,df没有直接的核心联系。实际上,我想生成一个6x6邻接矩阵,其中row 0column 0对应于Jackrow 1column 1对应于Anna,依此类推。

2 个答案:

答案 0 :(得分:1)

NetworkX返回的邻接矩阵是稀疏的。首先,将其转换为密集矩阵:

dense = nx.adjacency_matrix(G).todense()

创建一个数据框,其内容为邻接矩阵,并且行和列表示所有节点:

adj_df = pd.DataFrame(dense, index=G.nodes(), columns=G.nodes())

最后,采用df定义的数据帧子集:

adj_df.loc[df.Name, df.Name]
#        Jack  Anna  Emilie  Frank  John
#Jack       0     0       1      0     0
#Anna       0     0       0      0     0
#Emilie     1     0       0      0     0
#Frank      0     0       0      0     1
#John       0     0       0      1     0

答案 1 :(得分:0)

您可以通过手动添加节点和边来构造有向图:

def from_pandas_dataframe(df, col_from, col_to, col_weight=None, nodes=None):
    """Construct a digraph from dataframe.

    :param df: dataframe contains edge/relation information
    :param col_from: dataframe column name for start of edge
    :param col_to: dataframe column name for end of edge
    :param col_weight: dataframe column name for col_weight, defaults 1 if not provided
    :param nodes: nodes for the graph, default to use nodes from df if not provided
    :return:
    """
    g = nx.OrderedDiGraph()

    # add nodes
    if not nodes:
        nodes = set(df[col_from]) | set(df[col_to])
    g.add_nodes_from(nodes)

    # add edges
    for _, row in df.iterrows():
        from_node, to_node = row[col_from], row[col_to]
        if from_node in nodes and to_node in nodes:
            weight = 1 if not col_weight else row[col_weight]
            g.add_edge(from_node, to_node, weight=weight)

    return g

Param nodes指定图中的节点,没有节点的边将被省略:

g = from_pandas_dataframe(df1, 'Name1', 'Name2', col_weight='c', nodes=df['Name'].tolist())
adj = nx.adjacency_matrix(g)

运行示例数据:

>>> print(g.nodes)
['Jack', 'Anna', 'Emilie', 'Frank', 'John']
>>> print(adj)
  (2, 0)    3
  (3, 4)    1