Vedrete che questa risposta in realtà sarebbe fit better to your other question che è stato contrassegnato come duplicato di questo (e non so perché, perché non è la stessa domanda ...)
La presenza di zeri può infatti compromettere delle colonne o righe media, ad esempio:
a = np.array([[ 0, 1, 0.9, 1],
[0.9, 0, 1, 1],
[ 1, 1, 0, 0.5]])
senza eliminare le diagonali, sarebbe dire che il column 3
ha la media più alta, ma eliminando le diagonali la media più alta appartiene column 1
e ora column 3
ha il minor media di tutte le colonne ns!
è possibile correggere la media calcolata utilizzando la (minimo comune multiplo) lcm
del numero di linee con e senza le diagonali, garantendo che, quando un elemento diagonale non esiste la correzione non viene applicato:
correction = column_sum/lcm(len(column), len(column)-1)
new_mean = mean + correction
ho copiato l'algoritmo per lcm
from this answer e ha proposto una soluzione per il vostro caso:
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)
test con la a
di cui sopra:
mymean(a)
#array([ 0.95 , 1. , 0.95 , 0.83333333])
Con un altro esempio:
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 ])
Con la media corretta è sufficiente utilizzare np.argmax()
per ottenere l'indice di colonna con la media più alta. Analogamente, np.argmin()
per ottenere l'indice della colonna con la media minima:
np.argmin(mymean(a))