【问题标题】:Find most common value in numpy 2d array rows, otherwise return maximum在 numpy 二维数组行中查找最常见的值,否则返回最大值
【发布时间】:2022-01-09 07:04:47
【问题描述】:

我有一个这样的数组

Nbank = np.array([[2, 3, 1],
                  [1, 2, 2],
                  [3, 2, 1],
                  [3, 2, 1],
                  [2, 3, 2],
                  [2, 2, 3],
                  [1, 1, 3],
                  [2, 1, 1],
                  [2, 2, 3],
                  [1, 1, 1],
                  [2, 1, 1],
                  [2, 3, 1],
                  [1, 2, 1]])

我想返回一个只有一列的数组。条件是返回每一行中最常见的值;如果多个值的出现次数相同,则返回其中的最大值。

我用过这段代码

most_f = np.array([np.bincount(row).argmax() for row in Nbank])

如果多个值的出现次数相同,则返回第一项而不是最大值。我该如何解决这个问题?

【问题讨论】:

    标签: python arrays numpy


    【解决方案1】:

    您可以在按行降序排序后使用计数器。有一个most_common 会返回你想要的。由于它已经排序,第一个元素总是最大或最频繁的。

    import numpy as np
    from collections import Counter
    Nbank = np.array([[2, 3, 1],
                      [1, 2, 2],
                      [3, 2, 1],
                      [3, 2, 1],
                      [2, 3, 2],
                      [2, 2, 3],
                      [1, 1, 3],
                      [2, 1, 1],
                      [2, 2, 3],
                      [1, 1, 1],
                      [2, 1, 1],
                      [2, 3, 1],
                      [1, 2, 1]])
    
    
    np.array([Counter(sorted(row, reverse=True)).most_common(1)[0][0] for row in Nbank])
    

    输出

    array([3, 2, 3, 3, 2, 2, 1, 1, 2, 1, 1, 3, 1])
    

    【讨论】:

    • 问题是计数器对象的 API 是否承诺most_common 将进行稳定排序(而不是在当前实现中发生)。
    • alani 我对此一无所知,也许@Chris 可以回答这个问题。虽然这是可行的,但由于我不想使用 numpy 以外的其他模块,所以我没有选择这个回答。不过感谢您的努力,我很感激!
    • @OmarZaki 附加模块在这里并不是真正的问题,因为collections 在标准库中。
    • @alani 应该没问题docs.python.org/3/library/…
    • @Chris 感谢您的检查。我只是在查看文档字符串,没有那么彻底。
    【解决方案2】:

    我相信这会解决问题。您可能会通过一些花哨的列表理解将其变成一个单行,但我认为这不值得。

    most_f = []
    for n in Nbank: #iterate over elements
        counts = np.bincount(n) #count the number of elements of each value
        most_f.append(np.argwhere(counts == np.max(counts))[-1][0]) #append the last and highest
    

    【讨论】:

      【解决方案3】:

      您可以稍微作弊并反转每一行,以使np.argmax 返回对应于最大项目的最右边出现的索引:

      N = np.max(arr)
      >>> [N - np.argmax(np.bincount(row, minlength=N+1)[::-1]) for row in Nbank]
      [3, 2, 3, 3, 2, 2, 1, 1, 2, 1, 1, 3, 1]
      

      如果您想充分利用numpy,您可能还想避免循环,这绝对是可取的。不幸的是,二维数组不支持np.bincount,但您可以手动完成:

      N, M = arr.shape[0], np.max(arr)+1
      bincount_2D = np.zeros(shape=(N, M), dtype=int)
      advanced_indexing = np.repeat(np.arange(N), arr.shape[1]), arr.ravel()
      np.add.at(bincount_2D, advanced_indexing, 1)
      >>> bincount_2D
      array([[0, 1, 1, 1],
             [0, 1, 2, 0],
             [0, 1, 1, 1],
             [0, 1, 1, 1],
             [0, 0, 2, 1],
             [0, 0, 2, 1],
             [0, 2, 0, 1],
             [0, 2, 1, 0],
             [0, 0, 2, 1],
             [0, 3, 0, 0],
             [0, 2, 1, 0],
             [0, 1, 1, 1],
             [0, 2, 1, 0]])
      

      然后同时对所有行重复该过程:

      >>> M -1 - np.argmax(bincount_2D[:,::-1], axis=1)
      array([3, 2, 3, 3, 2, 2, 1, 1, 2, 1, 1, 3, 1], dtype=int64)
      

      【讨论】:

        猜你喜欢
        • 2015-05-09
        • 2015-04-06
        • 2014-06-28
        • 1970-01-01
        • 2016-04-14
        • 2017-04-03
        • 2019-03-31
        • 2021-08-31
        • 1970-01-01
        相关资源
        最近更新 更多