2013-06-12 13 views
7

Mam numpy tablicy tak:zastąpić zera w numpy tablicy z wartością mediany

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] 

Chcę wymienić wszystkie zer z medianą wartości całej tablicy (gdzie wartości zerowej nie są zostać uwzględnione w obliczaniu mediana)

do tej pory to dzieje:

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 

jest jakiś sprytny sposób, aby osiągnąć ten cel ze składnią numpy?

Dziękuję

Odpowiedz

16

Rozwiązanie to wykorzystuje 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 

Tylko uwaga uwaga, mediana dla swojej tablicy (bez zer) wynosi 23,5, ale jak napisano w tym kije 23.

+0

Zaczekaj chwilę ... Mediana powinna wynosić 26? Gdy niezerowa tablica elementów zostanie posortowana (3 5 8 14 15 16 17 18 19 21 26 27 29 29 31 38 38 40 49 55), wartość w środku wynosi 26. – slashdottir

+0

Nieważne, masz rację. To dobre rozwiązanie. – slashdottir

+0

Tak, istnieje 20 elementów niezerowych. Dwa w środku to 21 i 26. Mediana jest zwykle obliczana jako średnia z dwóch środkowych dla parzystej liczby elementów, więc otrzymujemy 23,5. Dzięki za przegraną! – bbayles

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

Zamiast foo2, można po prostu zaktualizować foo jeśli chcesz. Inteligentna składnia Numpy może łączyć kilka linii kodu, które stworzyłeś. Na przykład, zamiast,

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

Można po prostu zrobić

nz_values = foo[foo > 0] 

Możesz dowiedzieć się więcej o „wyszukane indeksowania” w documentation.

+0

tak chłodny, działa świetnie, dziękuję! – slashdottir