【问题标题】:How to convert an adjacency list into an adjacency matrix in Python [duplicate]如何在Python中将邻接列表转换为邻接矩阵[重复]
【发布时间】:2021-03-09 20:16:58
【问题描述】:

我有一个这样的邻接列表:

0 1 4 5
1 0 2 6
2 1 3 7
3 2 4 8
4 0 3 9
5 0 7 8
6 1 8 9
7 2 5 9
8 3 5 6
9 4 6 7

第一行表示0与1、4、5相邻;第二行表示 1 与 0、2 和 6 相邻;第三行是说 2 与 1、3 和 7 相邻,...

我怎样才能将它转换成这样的邻接矩阵?

0 1 0 0 1 1 0 0 0 0
1 0 1 0 0 0 1 0 0 0
0 1 0 1 0 0 0 1 0 0
0 0 1 0 1 0 0 0 1 0
1 0 0 1 0 0 0 0 0 1
1 0 0 0 0 0 0 1 1 0
0 1 0 0 0 0 0 0 1 1
0 0 1 0 0 1 0 0 0 1
0 0 0 1 0 1 1 0 0 0
0 0 0 0 1 0 1 1 0 0

【问题讨论】:

  • 你在使用 numpy 吗? a = np.zeros((10,10)) / a[0,[1,4,5]] = 1 会做到的。
  • 嘿@tim,感谢您的快速回复,我尝试了您的方法,它给了我这个矩阵:[[0. 1. 0. 0. 1. 1. 0. 0. 0. 0.] [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.] [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.] [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.] [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.] [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.] [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.] [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.] [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.] [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]][[0. 1. 0. 0. 1. 1. 0. 0. 0. 0.]
  • * 那个矩阵重复了几次,我是不是打错了?我以为您的“/”表示跳过一行
  • 我向您展示了第一行的示例,假设您可以将其扩展为处理所有内容的循环。我会发布一个答案来说明我的意思。

标签: python python-3.x adjacency-matrix adjacency-list


【解决方案1】:

如何在数据框中创建相同长度的定位 0 和 1 列表,然后将它们作为系列拉出。

# the lists will all be this length
maxlen = df.max().max()

df = pd.DataFrame([
    [0, 1, 4, 5],
    [1, 0, 2, 6],
    [2, 1, 3, 7],
    [3, 2, 4, 8],
    [4, 0, 3, 9],
    [5, 0, 7, 8],
    [6, 1, 8, 9],
    [7, 2, 5, 9],
    [8, 3, 5, 6],
    [9, 4, 6, 7]])

# the function used to create the lists
def createlist(x):
    arr=(maxlen+1)*[0]
    arr[x]=1
    return arr

# create the list for each cell, then concatenate the lists per row vertically, sum them, giving each final row
df2 = df.applymap(createlist).apply(lambda x: pd.concat([pd.Series(x[i]) for i in range(len(df.columns))], axis=1).sum(axis=1),axis=1)


df2

    0   1   2   3   4   5   6   7   8   9
0   1   1   0   0   1   1   0   0   0   0
1   1   1   1   0   0   0   1   0   0   0
2   0   1   1   1   0   0   0   1   0   0
3   0   0   1   1   1   0   0   0   1   0
4   1   0   0   1   1   0   0   0   0   1
5   1   0   0   0   0   1   0   1   1   0
6   0   1   0   0   0   0   1   0   1   1
7   0   0   1   0   0   1   0   1   0   1
8   0   0   0   1   0   1   1   0   1   0
9   0   0   0   0   1   0   1   1   0   1

要将对角线设置为零,请执行以下操作:

df3 = df2.values

np.fill_diagonal(df3, 0)

【讨论】:

  • 感谢@forgetso,没有考虑将其转换为熊猫数据框,这样操作起来更容易。快速提问,在引用自己时如何传递 0 而不是 1?例如0 应该在第一个单元格(不计算索引)中显示 0 而不是 1,1 应该在第 2 列第 2 行显示 0 而不是 1 等。此外,有什么方法可以删除列和行索引?
  • 您可以使用df3 = df2.values,然后填充对角线np.fill_diagonal(df3, 0)。您也可以将此应用于@Tim Roberts 的回答。看起来简单多了。
【解决方案2】:
import numpy as np
adj_dict = {}
path_to_list = '../adj_list.txt'
# Replace with zero if vertices are connected to themselves
empty_digonal = 1
with open(path_to_list) as f:
    adj_dict = {int(line.split()[0]):[int(x) for x in line.split()[empty_diagonal:]] for line in f.read().strip('\n').splitlines()}
adj_mx = np.zeros([len(adj_dict),len(adj_dict)])
for i in adj_dict:
        adj_mx[i,adj_dict[i]] = 1
assert sum(sum(adj_mx - adj_mx.T)) == 0, 'The matrix is not symmetric'

可能不是最佳解决方案,但它有效

【讨论】:

  • 谢谢@lotrus28,我收到回溯错误:文件“/tmp/source.py”,第 10 行,在 adj_mx[i,j] = 1 IndexError: index 1 is out轴 1 的大小为 1 我的代码:for line in sys.stdin: adj_dict = {} adj_dict = {int(line.split()[0]):[int(x) for x in line.split()[0:]] for line in line.strip('\n').splitlines()} adj_mx = np.zeros([len(adj_dict),len(adj_dict)]) for i in adj_dict: for j in adj_dict[i]: adj_mx[i,j] = 1 assert sum(sum(adj_mx - adj_mx.T)) == 0, print(adj_dict, end="")
  • @SilentP 表示您正在尝试使用j==1,此时j 的最大可接受值为0。你有一个“平面”矩阵。你确定输入不是一行?
【解决方案3】:
import numpy as np

rows = (
    [0, 1, 4, 5],
    [1, 0, 2, 6],
    [2, 1, 3, 7],
    [3, 2, 4, 8],
    [4, 0, 3, 9],
    [5, 0, 7, 8],
    [6, 1, 8, 9],
    [7, 2, 5, 9],
    [8, 3, 5, 6],
    [9, 4, 6, 7]
)

matrix = np.zeros((10,10))
for row in rows:
    matrix[row[0],row[1:]] = 1
print(matrix)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-19
    • 1970-01-01
    相关资源
    最近更新 更多