2013-06-30 9 views
5

Dato il seguente matrice:Trovare la riga con la media più alta in una matrice NumPy

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

desidero identificare la riga con la media più alta, escludendo gli zeri diagonali. Quindi, in questo caso, sarei in grado di identificare complete_matrix[:,3] come la riga con la media più alta.

risposta

2

Non è necessario preoccuparsi di 0 s, non devono influire sul confronto delle medie poiché ci sarà presumibilmente uno in ogni riga. Quindi, si può fare qualcosa di simile per ottenere l'indice della riga con la media più alta:

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

Riferimento:

7

Si noti che la presenza di gli zeri non influenzano quale riga ha la media più alta perché tutte le righe hanno lo stesso numero di elementi. Pertanto, prendiamo semplicemente la media di ogni riga, quindi chiediamo l'indice dell'elemento più grande.

#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 è ora l'indice della riga con la media più alta!

4

Come sottolineato da molte persone, la presenza di zeri non è un problema finché si ha lo stesso numero di zeri in ogni colonna. Nel caso in cui la tua intenzione fosse quella di ignorare tutti gli zeri, impedendo loro di partecipare al calcolo medio, potresti usare i pesi per sopprimere il contributo degli zeri. La seguente soluzione assegna 0 peso a zero, voci 1 altrimenti:

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

è sempre possibile creare una matrice peso dove il peso è 0 per elementi diagonali, e 1 altrimenti.

2

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 lcmfrom 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)) 
Problemi correlati