在numpy数组中查找平均值最高的行

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个回答

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


5

您不必担心 0,因为每行都应该有一个,所以它们不会影响平均值的比较。因此,您可以像这样做,以获取平均值最高的行的索引:

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

Reference:


经过一些测试(可能有误),但我认为 np.argmax(arr) 直接返回最高平均值,无需对列进行平均处理。 - FlyingZipper

4

正如许多人所指出的那样,只要每列中有相同数量的零,存在零并不是问题。但是,如果您的意图是忽略所有的零,使它们不参与平均计算,您可以使用权重来抑制零的贡献。以下解决方案将零条目分配为0权重,其他则为1:

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

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


2
你会发现,这个答案实际上更适合于你的另一个问题(链接),那个问题被标记为重复的,但我不知道为什么,因为它不是同一个问题...
例如,零的存在确实会影响列或行的平均值:
a = np.array([[  0, 1, 0.9,   1],
              [0.9, 0,   1,   1],
              [  1, 1,   0, 0.5]])

不消除对角线,它会告诉你第3列拥有最高的平均值,但是消除对角线后,最高的平均值属于第1列,现在第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))

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接