【问题标题】:Fastest way to get max frequency element for every row of numpy matrix获取每行 numpy 矩阵的最大频率元素的最快方法
【发布时间】:2021-11-23 15:46:52
【问题描述】:

给定一个 2d numpy 矩阵,形状为 [m,n] 的 X,其所有值都保证为 0 到 9 之间的整数,我希望为每一行计算该特定行中最常出现的值(打破平局,返回最大值),并输出这个长度为 m 的最大值数组。一个简短的例子如下:

X = [[1,2,3,4],
     [0,0,6,9],
     [5,7,7,5],
     [1,0,0,0],
     [1,8,1,8]]

上述矩阵的输出应该是:

y = [4,0,7,0,8]

考虑第一行 - 所有元素都以相同的频率出现,因此频率最高的数值最大值是 4。在第二行中,只有一个数字 0 频率最高。在第三行中,5 和 7 都出现了两次,因此选择了 7,以此类推。

我可以通过为每一行维护collections.Counter 对象然后选择满足条件的数字来做到这一点。我尝试过的一个幼稚的实现:

from collections import Counter 
X = np.array([[1,2,3,4],[0,0,6,9],[5,7,7,5],[1,0,0,0],[1,8,1,8]])
y = np.zeros(len(X), dtype=int)

for i in range (len(X)):
    freq_count = Counter (X[i])
    max_freq, max_freq_val = 0, -1
    for val in range (10):
        if (freq_count.get(val, 0) >= max_freq):
            max_freq = freq_count.get(val, 0)
            max_freq_val = val
    y[i] = max_freq_val

print (y) #prints [4 0 7 0 8]

但是使用计数器还不够快。是否可以提高运行时间?也许还使用矢量化?假设 m = O(5e4) 且 n = 45。

【问题讨论】:

    标签: python numpy matrix counter


    【解决方案1】:

    鉴于数字总是介于 0 和 9 之间的整数,您可以使用 numpy.bincount 计算出现次数,然后使用 numpy.argmax 查找最后一次出现(使用反向视图 [::-1]):

    import numpy as np
    
    X = np.array([[1, 2, 3, 4],
                  [0, 0, 6, 9],
                  [5, 7, 7, 5],
                  [1, 0, 0, 0],
                  [1, 8, 1, 8]])
    
    res = [9 - np.bincount(row, minlength=10)[::-1].argmax() for row in X]
    print(res)
    

    输出

    [4, 0, 7, 0, 8]
    

    根据时间here np.bincount 相当快。有关使用argmax 查找最大值的最后一次出现的更多详细信息,请阅读this

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-03-25
      • 2013-07-02
      • 1970-01-01
      • 2014-06-15
      • 2013-04-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多