'How to convert symmetric matrix to adjacency table
How could I convert symmetric matrix:
A B C D
A 1 2 3 4
B 2 1 2 3
C 3 2 1 2
D 4 3 2 1
into adjacency matrix?:
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
Is there any function?
Solution 1:[1]
Assuming a pandas dataframe as input, you can use numpy to get the 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]})
output:
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
all combinations
df.reset_index().melt('index', var_name='column')
output:
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
or, for a different order:
df.stack().rename_axis(['index', 'columns']).reset_index(name='value')
output:
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
Solution 2:[2]
Another solution is to use pandas.stack()
and reset the index values:
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
You can change the names of the columns as you wish.
Solution 3:[3]
It actually already is an adjacency matrix (as you would use it for a directed graph). I guess what you're looking for an Adjacency List or considering your example an Adjacency Map (for an undirected graph). I'm not sure if there is a built-in function for such a conversion (assuming you're using pandas dataframes considering the used tags). The easiest way of doing it is just reading the top (or just the bottom) triangle of the matrix which shouldn't take up too many iterations in a loop and just constructing it that way.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 | |
Solution 3 | David Hutter |