【问题标题】:Finding the row with the highest average in a numpy array在 numpy 数组中查找平均值最高的行
【发布时间】:2013-07-02 16:31:18
【问题描述】:

给定以下数组:

complete_matrix = numpy.array([
    [0, 1, 2, 4],
    [1, 0, 3, 5],
    [2, 3, 0, 6],
    [4, 5, 6, 0]])

我想找出平均值最高的行,不包括对角线零。 因此,在这种情况下,我可以将 complete_matrix[:,3] 识别为平均值最高的行。

【问题讨论】:

    标签: python arrays numpy


    【解决方案1】:

    请注意,零的存在不会影响哪一行的均值最高,因为所有行都有相同数量的元素。因此,我们只取每一行的均值,然后求最大元素的索引。

    #Take the mean along the 1st index, ie collapse into a Nx1 array of means
    means = np.mean(complete_matrix, 1)
    #Now just get the index of the largest mean
    idx = np.argmax(means)
    

    idx 现在是平均值最高的行的索引!

    【讨论】:

      【解决方案2】:

      您不必担心0s,它们不应该影响平均值的比较,因为大概每一行都会有一个。因此,您可以执行以下操作来获取平均值最高的行的索引:

      >>> import numpy as np 
      >>> complete_matrix = np.array([
      ...     [0, 1, 2, 4],
      ...     [1, 0, 3, 5],
      ...     [2, 3, 0, 6],
      ...     [4, 5, 6, 0]])
      >>> np.argmax(np.mean(complete_matrix, axis=1))
      3
      

      参考:

      【讨论】:

      • 经过一些测试(可能是错误的),但我认为 np.argmax(arr) 直接返回最高平均值,而无需计算列的平均值
      【解决方案3】:

      正如很多人所指出的,只要每列中的零数量相同,零的存在就不是问题。万一您的意图是忽略所有零,阻止它们参与平均计算,您可以使用权重来抑制零的贡献。以下解决方案将 0 权重分配给零个条目,否则为 1:

      numpy.argmax(numpy.average(complete_matrix,axis=0, weights=complete_matrix!=0))
      

      您始终可以创建一个权重矩阵,其中对角线条目的权重为 0,否则为 1。

      【讨论】:

        【解决方案4】:

        你会看到这个答案实际上会fit better to your other question被标记为与这个重复(不知道为什么,因为它不是同一个问题......)

        零的存在确实会影响列或行的平均值,例如:

        a = np.array([[  0, 1, 0.9,   1],
                      [0.9, 0,   1,   1],
                      [  1, 1,   0, 0.5]])
        

        如果不消除对角线,它会告诉column 3 具有最高的平均值,但消除对角线的最高平均值属于column 1,现在column 3 具有所有列中最低的平均值!

        您可以使用带和不带对角线的行数的lcm(最小公倍数)来校正计算的平均值,方法是保证在不存在对角线元素的情况下不应用校正:

        correction = column_sum/lcm(len(column), len(column)-1)
        new_mean = mean + correction
        

        我复制了lcmfrom this answer 的算法,并为您的情况提出了解决方案:

        import numpy as np
        
        def gcd(a, b):
            """Return greatest common divisor using Euclid's Algorithm."""
            while b:
                a, b = b, a % b
            return a
        
        def lcm(a, b):
            """Return lowest common multiple."""
            return a * b // gcd(a, b)
        
        def mymean(a):
            if len(a.diagonal()) < a.shape[1]:
                tmp = np.hstack((a.diagonal()*0+1,0))
            else:
                tmp = a.diagonal()*0+1
            return np.mean(a, axis=0) + np.sum(a,axis=0)*tmp/lcm(a.shape[0],a.shape[0]-1)
        

        使用上面给出的a 进行测试:

        mymean(a)
        #array([ 0.95      ,  1.        ,  0.95      ,  0.83333333])
        

        再举一个例子:

        b = np.array([[  0, 1, 0.9,   0],
                      [0.9, 0,   1,   1],
                      [  1, 1,   0, 0.5],
                      [0.9, 0.2,   1,   0],
                      [  1, 1,   0.7, 0.5]])
        
        mymean(b)
        #array([ 0.95,  0.8 ,  0.9 ,  0.5 ])
        

        使用修正后的平均值,您只需使用np.argmax() 即可获得平均值最高的列索引。同理,np.argmin() 获取平均最低的列的索引:

        np.argmin(mymean(a))
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2021-06-18
          • 1970-01-01
          • 2014-06-11
          • 2016-06-04
          • 2017-07-20
          • 2022-10-04
          • 1970-01-01
          相关资源
          最近更新 更多