8

给定以下数组:

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

我想确定具有最高平均值的行,不包括对角线零。因此,在这种情况下,我将能够识别complete_matrix[:,3]为具有最高平均值的行。

4

4 回答 4

7

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

#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 现在是平均值最高的行的索引!

于 2013-06-30T22:55:43.330 回答
5

您不必担心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

参考:

于 2013-06-30T22:53:46.600 回答
4

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

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

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

于 2013-07-01T16:23:00.433 回答
2

您会看到这个答案实际上更适合您标记为与该问题重复的其他问题(并且不知道为什么,因为它不是同一个问题......)

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

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

lcm 我从这个答案中复制了算法,并为您的案例提出了一个解决方案:

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))
于 2013-07-02T08:14:06.607 回答