给定以下数组:
complete_matrix = numpy.array([
[0, 1, 2, 4],
[1, 0, 3, 5],
[2, 3, 0, 6],
[4, 5, 6, 0]])
我希望能够找出平均值最高的行,但要排除对角线上的零元素。 因此,在这种情况下,我可以确定
complete_matrix[:,3]
是具有最高平均值的行。请注意,零的存在不会影响哪一行具有最高平均值,因为所有行具有相同数量的元素。因此,我们只需取每行的平均值,然后询问最大元素的索引。
#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现在是具有最高平均值的行的索引!
您不必担心 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:
正如许多人所指出的那样,只要每列中有相同数量的零,存在零并不是问题。但是,如果您的意图是忽略所有的零,使它们不参与平均计算,您可以使用权重来抑制零的贡献。以下解决方案将零条目分配为0权重,其他则为1:
numpy.argmax(numpy.average(complete_matrix,axis=0, weights=complete_matrix!=0))
您可以始终创建一个权重矩阵,其中对角线条目的权重为0,其余为1。
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))