如何将对称矩阵转换为邻接table
How to convert symmetric matrix to adjacency table
如何转换对称矩阵:
A B C D
A 1 2 3 4
B 2 1 2 3
C 3 2 1 2
D 4 3 2 1
进入邻接矩阵?:
A A 1
A B 2
A C 3
A D 4
B A 3
B B 1
B C 2
B D 3
C A 3
C C 1
C D 2
D A 4
D B 3
D C 2
D D 1
有什么功能吗?
它实际上已经是一个邻接矩阵(就像您将它用于有向图一样)。
我猜你正在寻找邻接列表或考虑你的示例邻接图(对于无向图)。
我不确定这种转换是否有 built-in 函数(假设您使用的是 pandas 数据帧,考虑到使用的标签)。
最简单的方法是只读取矩阵的顶部(或底部)三角形,它不应该在循环中占用太多迭代并以这种方式构建它。
假设一个 pandas 数据帧作为输入,你可以使用 numpy 得到 triu_indices
:
import pandas as pd
import numpy as np
l = [[1, 2, 3, 4], [2, 1, 2, 3], [3, 2, 1, 2], [4, 3, 2, 1]]
df = pd.DataFrame(l, index=list('ABCD'), columns=list('ABCD'))
# A B C D
# A 1 2 3 4
# B 2 1 2 3
# C 3 2 1 2
# D 4 3 2 1
a = df.to_numpy()
x,y = np.triu_indices(len(df))
out = pd.DataFrame({'x': df.index[x], 'y': df.columns[y], 'value': a[x,y]})
输出:
x y value
0 A A 1
1 A B 2
2 A C 3
3 A D 4
4 B B 1
5 B C 2
6 B D 3
7 C C 1
8 C D 2
9 D D 1
所有组合
df.reset_index().melt('index', var_name='column')
输出:
index column value
0 A A 1
1 B A 2
2 C A 3
3 D A 4
4 A B 2
5 B B 1
6 C B 2
7 D B 3
8 A C 3
9 B C 2
10 C C 1
11 D C 2
12 A D 4
13 B D 3
14 C D 2
15 D D 1
或者,对于不同的顺序:
df.stack().rename_axis(['index', 'columns']).reset_index(name='value')
输出:
index columns value
0 A A 1
1 A B 2
2 A C 3
3 A D 4
4 B A 2
5 B B 1
6 B C 2
7 B D 3
8 C A 3
9 C B 2
10 C C 1
11 C D 2
12 D A 4
13 D B 3
14 D C 2
15 D D 1
另一个解决方案是使用 pandas.stack()
并重置索引值:
import pandas as pd
import numpy as np
l = [[1, 2, 3, 4], [2, 1, 2, 3], [3, 2, 1, 2], [4, 3, 2, 1]]
df = pd.DataFrame(l, index=list('ABCD'), columns=list('ABCD'))
# A B C D
# A 1 2 3 4
# B 2 1 2 3
# C 3 2 1 2
# D 4 3 2 1
df = df.stack().reset_index()
df['ordered-name'] = df.apply(lambda x: '-'.join(sorted([x['level_0'],x['level_1']])),axis=1)
df = df.drop_duplicates(['ordered-name'])
df.drop(['ordered-name'], axis=1, inplace=True)
# level_0 level_1 0
# 0 A A 1
# 1 A B 2
# 2 A C 3
# 3 A D 4
# 4 B B 1
# 5 B C 2
# 6 B D 3
# 7 C C 1
# 8 C D 2
# 9 D D 1
您可以根据需要更改列的名称。
如何转换对称矩阵:
A B C D
A 1 2 3 4
B 2 1 2 3
C 3 2 1 2
D 4 3 2 1
进入邻接矩阵?:
A A 1
A B 2
A C 3
A D 4
B A 3
B B 1
B C 2
B D 3
C A 3
C C 1
C D 2
D A 4
D B 3
D C 2
D D 1
有什么功能吗?
它实际上已经是一个邻接矩阵(就像您将它用于有向图一样)。 我猜你正在寻找邻接列表或考虑你的示例邻接图(对于无向图)。 我不确定这种转换是否有 built-in 函数(假设您使用的是 pandas 数据帧,考虑到使用的标签)。 最简单的方法是只读取矩阵的顶部(或底部)三角形,它不应该在循环中占用太多迭代并以这种方式构建它。
假设一个 pandas 数据帧作为输入,你可以使用 numpy 得到 triu_indices
:
import pandas as pd
import numpy as np
l = [[1, 2, 3, 4], [2, 1, 2, 3], [3, 2, 1, 2], [4, 3, 2, 1]]
df = pd.DataFrame(l, index=list('ABCD'), columns=list('ABCD'))
# A B C D
# A 1 2 3 4
# B 2 1 2 3
# C 3 2 1 2
# D 4 3 2 1
a = df.to_numpy()
x,y = np.triu_indices(len(df))
out = pd.DataFrame({'x': df.index[x], 'y': df.columns[y], 'value': a[x,y]})
输出:
x y value
0 A A 1
1 A B 2
2 A C 3
3 A D 4
4 B B 1
5 B C 2
6 B D 3
7 C C 1
8 C D 2
9 D D 1
所有组合
df.reset_index().melt('index', var_name='column')
输出:
index column value
0 A A 1
1 B A 2
2 C A 3
3 D A 4
4 A B 2
5 B B 1
6 C B 2
7 D B 3
8 A C 3
9 B C 2
10 C C 1
11 D C 2
12 A D 4
13 B D 3
14 C D 2
15 D D 1
或者,对于不同的顺序:
df.stack().rename_axis(['index', 'columns']).reset_index(name='value')
输出:
index columns value
0 A A 1
1 A B 2
2 A C 3
3 A D 4
4 B A 2
5 B B 1
6 B C 2
7 B D 3
8 C A 3
9 C B 2
10 C C 1
11 C D 2
12 D A 4
13 D B 3
14 D C 2
15 D D 1
另一个解决方案是使用 pandas.stack()
并重置索引值:
import pandas as pd
import numpy as np
l = [[1, 2, 3, 4], [2, 1, 2, 3], [3, 2, 1, 2], [4, 3, 2, 1]]
df = pd.DataFrame(l, index=list('ABCD'), columns=list('ABCD'))
# A B C D
# A 1 2 3 4
# B 2 1 2 3
# C 3 2 1 2
# D 4 3 2 1
df = df.stack().reset_index()
df['ordered-name'] = df.apply(lambda x: '-'.join(sorted([x['level_0'],x['level_1']])),axis=1)
df = df.drop_duplicates(['ordered-name'])
df.drop(['ordered-name'], axis=1, inplace=True)
# level_0 level_1 0
# 0 A A 1
# 1 A B 2
# 2 A C 3
# 3 A D 4
# 4 B B 1
# 5 B C 2
# 6 B D 3
# 7 C C 1
# 8 C D 2
# 9 D D 1
您可以根据需要更改列的名称。