从电子表格以 Python 方式创建邻接矩阵

Posted

技术标签:

【中文标题】从电子表格以 Python 方式创建邻接矩阵【英文标题】:Pythonically create adjacency matrix from spreadsheet 【发布时间】:2021-08-24 19:56:03 【问题描述】:

我有一个电子表格,其中列出了某个特定人员报告的在多个项目中与之合作的人员名单。如果我将它作为数据框导入 pandas,它将如下所示:

       1                  2
Jane   ['Fred', 'Joe']    ['Joe', 'Fred', 'Bob']
Fred   ['Alex']           ['Jane']
Terry  NaN                ['Bob']
Bob    ['Joe']            ['Jane', 'Terry']
Alex   ['Fred']           NaN
Joe    ['Jane']           ['Jane']

我想创建一个如下所示的邻接矩阵:

      Jane  Fred  Terry  Bob  Alex  Joe
Jane  0     2     0      1    0     2
Fred  1     0     0      0    1     0
Terry 0     0     0      1    0     0
Bob   1     0     1      0    0     1
Alex  0     1     0      0    0     0
Joe   2     0     0      0    0     0

这个矩阵通常不会是对称的,因为与人们的报告不一致。我一直在通过循环遍历数据框并相应地递增矩阵元素来创建邻接矩阵。显然,不推荐循环遍历数据帧并且效率低下,那么有没有人建议他如何以更 Python 的方式完成?

【问题讨论】:

只是检查一下,单元格的内容是list?你能用type(df.iloc[0,0])验证吗 好问题,当我导入数据时,它实际上是以 '[Name1, Name2, ...]' 形式的字符串出现的,但我应用了一个 string2list() 函数来打开将所有单元格的内容放入列表中。但是,简而言之,答案是肯定的,每个单元格的类型都是list(除非是np.NaN)。顺便说一句,我实际上没有名字,而是整数 ID 号(名字已经匿名)所以每个单元格的内容实际上是一个整数列表。 【参考方案1】:

这是我曾经使用过的数据样本。

df = pd.DataFrame(
    'Name': ['Jane', 'Fred', 'Terry', 'Bob', 'Alex', 'Joe'],
    '1':[['Fred', 'Joe'], ['Alex'], np.nan,['Joe'], ['Fred'], ['Jane']],
    '2': [['Joe', 'Fred', 'Bob'], ['Jane'], ['Bob'], ['Jane', 'Terry'], np.nan, ['Jane']]
)

df.head()
    Name            1                 2
0   Jane  [Fred, Joe]  [Joe, Fred, Bob]
1   Fred       [Alex]            [Jane]
2  Terry          NaN             [Bob]
3    Bob        [Joe]     [Jane, Terry]
4   Alex       [Fred]               NaN

我通过三个简单的步骤使用 pandas 创建了邻接矩阵。

首先,我将数据融合为仅用于不同名称之间的所有连接的一列,并删除了变量列。

dff = df.melt(id_vars=['Name']).drop('variable', axis=1)
     Name             value
0    Jane       [Fred, Joe]
1    Fred            [Alex]
2   Terry               NaN
3     Bob             [Joe]
4    Alex            [Fred]
5     Joe            [Jane]
6    Jane  [Joe, Fred, Bob]
7    Fred            [Jane]
8   Terry             [Bob]
9     Bob     [Jane, Terry]
10   Alex               NaN
11    Joe            [Jane]

其次,我使用了explode方法将行分解为单独的行。

dff = dff.explode('value')
     Name  value
0    Jane   Fred
0    Jane    Joe
1    Fred   Alex
2   Terry    NaN
3     Bob    Joe
4    Alex   Fred
5     Joe   Jane
6    Jane    Joe
6    Jane   Fred
6    Jane    Bob
7    Fred   Jane
8   Terry    Bob
9     Bob   Jane
9     Bob  Terry
10   Alex    NaN
11    Joe   Jane

最后,为了创建邻接矩阵,我在 pandas 中使用了交叉表,它只计算指定的两列中的出现次数。

pd.crosstab(dff['Name'], dff['value'])
value  Alex  Bob  Fred  Jane  Joe  Terry
Name                                    
Alex      0    0     1     0    0      0
Bob       0    0     0     1    1      1
Fred      1    0     0     1    0      0
Jane      0    1     2     0    2      0
Joe       0    0     0     2    0      0
Terry     0    1     0     0    0      0

【讨论】:

这太棒了,正是我想要的。谢谢!【参考方案2】:

这是一种方法:

import pandas as pd
import ast

data = '''       1                  2
Jane   ['Fred', 'Joe']    ['Joe', 'Fred', 'Bob']
Fred   ['Alex']           ['Jane']
Terry  NaN                ['Bob']
Bob    ['Joe']            ['Jane', 'Terry']
Alex   ['Fred']           NaN
Joe    ['Jane']           ['Jane']'''

df = pd.read_csv(io.StringIO(data), sep='\s\s+', engine='python').fillna('[]').applymap(ast.literal_eval) #if your columns are already lists rather than string representations, use .fillna([]) and skip the applymap
df['all'] = df['1']+df['2'] #merge lists of columns 1 and 2

df_edges = df[['all']].explode('all').reset_index() #create new df by exploding the combined list
df_edges = df_edges.groupby(['index', 'all'])['all'].count().reset_index(name="count") #groupby and count the pairs

df_edges.pivot(index='index', columns='all', values='count').fillna(0) #create adjacency matrix with pivot

输出:

index Alex Bob Fred Jane Joe Terry
Alex 0 0 1 0 0 0
Bob 0 0 0 1 1 1
Fred 1 0 0 1 0 0
Jane 0 1 2 0 2 0
Joe 0 0 0 2 0 0
Terry 0 1 0 0 0 0

【讨论】:

以上是关于从电子表格以 Python 方式创建邻接矩阵的主要内容,如果未能解决你的问题,请参考以下文章

图的存储结构:邻接矩阵(邻接表)&链式前向星

在 Python 中为大型数据集创建邻接矩阵

数据结构与算法图 ( 图的存储形式 | 图的基本概念 | 图的表示方式 | 邻接矩阵 | 邻接表 | 图的创建 | 代码示例 )

求算法,用邻接矩阵和邻接表创建一个图,实现深度和广度搜索,菜单形式,c语言的代码。无向无权的图。

数据结构与算法学习笔记 图

数据结构与算法学习笔记 图