将非方阵邻接矩阵导入到 Networkx Python 中

5
我有一些数据以pandas dataframe的形式呈现,其中列代表离散的技能,行代表离散的职位。只有当该技能是工作所必需的时,才会出现1,否则为0。
     skill_1, skill_2,
job_1      1,       0,       
job_2      0,       0,       
job_3      1,       1,       

我想使用networkx创建一个图来可视化职位和技能之间的关系。我尝试了两种方法,一个是在数据帧本身上使用nx.from_pandas_adjacency,另一个是应用于数据帧的numpy表示形式的nx.from_numpy_matrix,其中删除了列和行名称。
但由于这是一个非方阵矩阵,因此产生了错误。这很有道理,因为networkx可能会将列和行都解释为同一组节点。然而,在这里,列和节点代表着完全不同的事物。两个职位通过他们所共享的技能相互连接,而两个技能则通过他们所共享的职位相互连接,但是任何两个技能或任何两个职位之间都没有直接的边缘连接。
如何将我的数据导入到networkx中,考虑到我的行和列是不同的节点集?
3个回答

2

1

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

(我对实现向量化方法很好奇,所以我问了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))

Which gives us:

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

0

正如ComplexGates所提到的,您在这里拥有的是一个双向邻接矩阵。我看到您已经添加了一种解决方案,即用零填充其余矩阵以使其成为正方形。然而,我怀疑您真正想要的是如何将双向邻接矩阵转换为(正方形)邻接矩阵,这与发布的解决方案不同。

对于具有m行和n列的双向邻接矩阵A,您可以将其转换为大小为(m + n)x(m + n)的邻接矩阵,方法如下:

┏           ┓
┃0_nxn A^T  ┃
┃A_mxn 0_mxm┃
┗           ┛

换句话说,将A放在(m+n)x(m+n)矩阵的左下角,将A的转置放在右上角,并用零填充其余空间。
在代码中,如果A是一个2D Numpy数组,你可以这样做:
def bipartite_to_adjacency(A):
     m, n = A.shape
     Z_mm = np.zeros((m,m), dtype=int)
     Z_nn = np.zeros((n,n), dtype=int)
     top_partition = np.concatenate((Z_nn,np.transpose(A)), axis=1)
     bottom_partition = np.concatenate((A,Z_mm), axis=1)
     return np.concatenate((top_partition, bottom_partition))

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接