【问题标题】:Construct an assignment matrix - Python构造一个赋值矩阵 - Python
【发布时间】:2019-05-13 06:28:11
【问题描述】:

我有两个元素列表

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

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

【问题讨论】:

    标签: python matrix variable-assignment


    【解决方案1】:

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

    【讨论】:

    • 这在这个例子中可以正常工作,因为它已经完美匹配了。如果我使用更复杂的列表(不是完美匹配),有时元素不会唯一匹配(匹配中的一个元素与 b 中的 2 个或更多元素)
    • @ThanhNguyen 我不确定我是否理解您,但如果您希望我帮助您,请显示您的预期输出以获取更多详细信息。
    • 这是我数据的结果:{1.0: array([34]), 2.0: array([32]), 3.0: array([32]), 4.0: array([16 ]), 5.0: 数组([21]), 6.0: 数组([30]), 7.0: 数组([1]), 8.0: 数组([13]), 9.0: 数组([31]), 10.0:数组([6]),11.0:数组([21]),12.0:数组([40]),13.0:数组([40]),14.0:数组([36])}。可以看到,2、3都匹配到32,12、13都匹配到40。因为我的list很长,所以我在问题里放了一个玩具例子。
    【解决方案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))
    

    【讨论】:

      【解决方案3】:

      如果您期望输出,因为我们如何将矩阵指定为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)) 
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-01-01
        • 1970-01-01
        • 2020-11-19
        • 2019-05-24
        • 2018-07-16
        • 2015-04-24
        相关资源
        最近更新 更多