2013-06-12 15 views
7

Ho una matrice NumPy simili:sostituire zeri in matrice numpy con il valore mediano

foo_array = [38,26,14,55,31,0,15,8,0,0,0,18,40,27,3,19,0,49,29,21,5,38,29,17,16] 

voglio sostituire tutti gli zeri con il valore mediano l'intero array (dove i valori zero non sono essere inclusi nel calcolo della mediana)

Finora ho questo succede:

foo_array = [38,26,14,55,31,0,15,8,0,0,0,18,40,27,3,19,0,49,29,21,5,38,29,17,16] 
foo = np.array(foo_array) 
foo = np.sort(foo) 
print "foo sorted:",foo 
#foo sorted: [ 0 0 0 0 0 3 5 8 14 15 16 17 18 19 21 26 27 29 29 31 38 38 40 49 55] 
nonzero_values = foo[0::] > 0 
nz_values = foo[nonzero_values] 
print "nonzero_values?:",nz_values 
#nonzero_values?: [ 3 5 8 14 15 16 17 18 19 21 26 27 29 29 31 38 38 40 49 55] 
size = np.size(nz_values) 
middle = size/2 
print "median is:",nz_values[middle] 
#median is: 26 

esiste un modo intelligente per raggiungere questo obiettivo con la sintassi numpy?

Grazie

risposta

16

Questa soluzione sfrutta numpy.median:

import numpy as np 
foo_array = [38,26,14,55,31,0,15,8,0,0,0,18,40,27,3,19,0,49,29,21,5,38,29,17,16] 
foo = np.array(foo_array) 
# Compute the median of the non-zero elements 
m = np.median(foo[foo > 0]) 
# Assign the median to the zero elements 
foo[foo == 0] = m 

Solo una nota di cautela, la mediana per l'array (senza zeri) è 23,5, ma come scritto questo bastoni in 23.

+0

Aspetta un minuto ... La mediana dovrebbe essere 26? Quando l'array di elementi diverso da zero viene ordinato (3 5 8 14 15 16 17 18 19 21 26 27 29 29 31 38 38 40 49 55), il valore nel mezzo è 26. – slashdottir

+0

Nevermind, hai ragione. Questa è una buona soluzione – slashdottir

+0

Sì, ci sono 20 elementi diversi da zero. I due al centro sono 21 e 26. La mediana di solito è calcolata come la media dei due nel mezzo per un numero pari di elementi, quindi otteniamo 23,5. Grazie per l'upvote! – bbayles

1
foo2 = foo[:] 
foo2[foo2 == 0] = nz_values[middle] 

Invece di foo2, si può solo aggiornare foo se si desidera. La sintassi degli smart array di Numpy può combinare alcune righe del codice che hai creato. Ad esempio, invece di,

nonzero_values = foo[0::] > 0 
nz_values = foo[nonzero_values] 

Si può solo fare

nz_values = foo[foo > 0] 

È possibile trovare maggiori informazioni su "indicizzazione fantasia" nel documentation.

+0

così fresco, funziona alla grande, grazie! – slashdottir

Problemi correlati