构造分配矩阵-Python

时间:2018-12-12 07:36:35

标签: python matrix variable-assignment

我有两个元素列表

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.]]

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

3 个答案:

答案 0 :(得分:3)

您甚至不需要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]})

答案 1 :(得分:1)

此行:

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))

答案 2 :(得分:0)

如果您期望输出,则因为我们如何将矩阵指定为a(i, j)i是行的索引,而j是col的索引。查看矩阵中的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))