将非平方邻接矩阵导入Networkx Python

2022-03-31 00:00:00 python numpy pandas networkx graph-theory

问题描述

我在下面的 pandas 数据框表格中有一些数据,其中列代表离散技能,行代表离散工作。仅当作业需要技能时,才会显示1,否则为0。

     skill_1, skill_2,
job_1      1,       0,       
job_2      0,       0,       
job_3      1,       1,       

我想使用networkx创建一个图表来可视化工作和技能之间的这种关系。我尝试了两种方法,一种是在数据帧本身上,nx.from_pandas_adjacencynx.from_numpy_matrix。后一种方法被应用于数据帧的数字表示,其中删除了列名和行名。

在任何一种情况下,都会引发错误,因为这是一个非方阵。这是有意义的,因为networkx可能会将列和行解释为同一组节点。然而,列和节点在这里代表了截然不同的东西。两个工作通过它们共享的技能联系在一起,两个技能通过它们共享的工作联系在一起,但任何两种技能或任何两种工作之间都没有直接的优势。

如果我的行和列是不同的节点集,如何将数据导入到networkx?


解决方案

一种选择是生成缺少的行和列

(我对实现这一点的矢量化方法很好奇,所以我问了this question谁有提供这种方法的答案。)

df = pd.DataFrame({'skill_1': {'job_1': 1, 'job_2': 0, 'job_3': 1},
 'skill_2': {'job_1': 0, 'job_2': 0, 'job_3': 1}})

edges = df.columns

for i in df.index:
    df[i] = [0 for _ in range(len(df.index))]

for e in edges:
    df = df.append(pd.Series({c:0 for c in df.columns},name=e))

这为我们提供了:

>>> df
         skill_1  skill_2  job_1  job_2  job_3
job_1          1        0      0      0      0
job_2          0        0      0      0      0
job_3          1        1      0      0      0
skill_1        0        0      0      0      0
skill_2        0        0      0      0      0

然后我们可以使用nx.from_pandas_adjacency读取到networkx(假设您需要有向图)

G = nx.from_pandas_adjacency(df, create_using=nx.DiGraph)

或者,我们可以使用df.STACK()

df = pd.DataFrame({'skill_1': {'job_1': 1, 'job_2': 0, 'job_3': 1},
 'skill_2': {'job_1': 0, 'job_2': 0, 'job_3': 1}})

G = nx.DiGraph()

for x,y in df.stack().reset_index().iterrows():
    G.add_node(y['level_0'])
    G.add_node(y['level_1'])
    if y[0]:
        G.add_edge(y['level_0'], y['level_1'])

相关文章