构建分配矩阵 - Python

Construct an assignment matrix - Python

我有两个元素列表

a = [1,2,3,2,3,1,1,1,1,1]
b = [3,1,2,1,2,3,3,3,3,3]

并且我正在尝试唯一匹配 a 到 b 的元素,我的预期结果是这样的:

1: 3
2: 1
3: 2

所以我尝试构造一个赋值矩阵然后使用scipy.linear_sum_assignment

a = [1,2,3,2,3,1,1,1,1,1]
b = [3,1,2,1,2,3,3,3,3,3]

total_true = np.unique(a)
total_pred = np.unique(b)

matrix = np.zeros(shape=(len(total_pred),
                         len(total_true)
                         )
                  )

for n, i in enumerate(total_true):
    for m, j in enumerate(total_pred):
        matrix[n, m] = sum(1 for item in b if item==(i))

我预计矩阵是:

  1 2 3
1 0 2 0
2 0 0 2
3 6 0 0

但是输出是:

[[2. 2. 2.]
 [2. 2. 2.]
 [6. 6. 6.]]

我在这里犯了什么错误?非常感谢

你甚至不需要 Pandas 处理这个。尝试使用 zipdict:

In [42]: a = [1,2,3,2,3,1,1,1,1,1]
    ...: b = [3,1,2,1,2,3,3,3,3,3]
    ...: 

In [43]: c =zip(a,b)

In [44]: dict(c)
Out[44]: {1: 3, 2: 1, 3: 2}

UPDATE 正如 OP 所说,如果我们需要使用相同的键存储所有值,我们可以使用 defaultdict:

In [58]: from collections import defaultdict

In [59]: d = defaultdict(list)

In [60]: for k,v in c:
    ...:     d[k].append(v)
    ...:     

In [61]: d
Out[61]: defaultdict(list, {1: [3, 3, 3, 3, 3, 3], 2: [1, 1], 3: [2, 2]})

这一行:

matrix[n, m] = sum(1 for item in b if item==(i))

计算ib中出现的次数,并将结果保存到matrix[n, m]。矩阵的每个单元格将包含 b 中 1 的数量(即 2)或 b 中 2 的数量(即 2)或 b 中 3 的数量(即6).请注意,此值完全独立于 j,这意味着一行中的值将始终相同。

为了考虑j,尝试将行替换为:

matrix[n, m] = sum(1 for x, y in zip(a, b) if (x, y) == (j, i))

以防您的预期输出,因为我们如何将矩阵指定为 a(i, j),其中 i 是行的索引,j 是列的索引。查看矩阵中的 a(3,1),结果为 6,这意味着 (3,1) 组合匹配 6 次,其中 3 次来自 b,1 次来自 a。我们可以从 2 个列表中找到所有匹配项。

matches = [tuple([x, y]) for x,y in zip(b, a)]

然后我们可以找到特定组合有多少匹配,例如a(3, 1)。

result = matches.count((3,1))