2016-02-12 14 views
5

Rozważyć obliczeń histogram numpy tablicy, która powraca procentowe:filtrowania krawędzi histogramu i liczby

# 500 random numbers between 0 and 10,000 
values = np.random.uniform(0,10000,500) 

# Histogram using e.g. 200 buckets 
perc, edges = np.histogram(values, bins=200, 
          weights=np.zeros_like(values) + 100/values.size) 

Powyższe zwraca dwie macierze:

  • perc zawierający % (czyli w procentach) od wartości w każdej pary kolejnych następujących po sobie edges[ix] i.
  • edges długości len(hist)+1

Teraz, powiedzmy, że chcę, aby filtrować perc i edges tak, że tylko skończyć z procentów i krawędzi dla wartości zawartych w nowej gamy [m, M]. "

Oznacza to, że chcę pracować z sub-macierzy z perc i edges odpowiadających przedziale wartości ciągu [m, M]. Nie trzeba dodawać, że nowa tablica wartości procentowych nadal odnosiłaby się do całkowitej liczby frakcji tablicy wejściowej. Chcemy tylko przefiltrować perc i edges, aby zakończyć się poprawnymi pod-tablicami.

Jak mogę postprocesować perc i edges, aby to zrobić?

Wartości m i M mogą być dowolną liczbą oczywiście. W powyższym przykładzie możemy założyć np. m = 0 i M = 200. praca

Odpowiedz

2
m = 0; M = 200 
mask = [(m < edges) & (edges < M)] 
>>> edges[mask] 
array([ 37.4789683 , 87.07491593, 136.67086357, 186.2668112 ]) 

Miejmy na mniejszym zbiorze, dzięki czemu łatwiej jest zrozumieć:

np.random.seed(0) 
values = np.random.uniform(0, 100, 10) 
values.sort() 
>>> values 
array([ 38.34415188, 42.36547993, 43.75872113, 54.4883183 , 
     54.88135039, 60.27633761, 64.58941131, 71.51893664, 
     89.17730008, 96.36627605]) 

# Histogram using e.g. 10 buckets 
perc, edges = np.histogram(values, bins=10, 
          weights=np.zeros_like(values) + 100./values.size) 

>>> perc 
array([ 30., 0., 20., 10., 10., 10., 0., 0., 10., 10.]) 

>>> edges 
array([ 38.34415188, 44.1463643 , 49.94857672, 55.75078913, 
     61.55300155, 67.35521397, 73.15742638, 78.9596388 , 
     84.76185122, 90.56406363, 96.36627605]) 

m = 0; M = 50 
mask = (m <= edges) & (edges < M) 
>>> mask 
array([ True, True, True, False, False, False, False, False, False, 
     False, False], dtype=bool) 

>>> edges[mask] 
array([ 38.34415188, 44.1463643 , 49.94857672]) 

>>> perc[mask[:-1]][:-1] 
array([ 30., 0.]) 

m = 40; M = 60 
mask = (m < edges) & (edges < M) 
>>> edges[mask] 
array([ 44.1463643 , 49.94857672, 55.75078913]) 
>>> perc[mask[:-1]][:-1] 
array([ 0., 20.]) 
+0

Dzięki, ale jak mamy teraz używać 'mask' również filtrować' perc'? –

1

Więc może trzeba trochę matematyki dla tego produktu. Pojemniki są równomiernie rozmieszczone w taki sposób można określić, który bin jest pierwszym, który obejmuje i który jest ostatnią za pomocą szerokość każdego kosza:

bin_width = edges[1] - edges[0] 

teraz obliczyć pierwszy i ostatni ważny BIN:

first = math.floor((m - edges[0])/bin_width) + 1 # How many bins from the left 
last = math.floor((edges[-1] - M)/bin_width) + 1 # How many bins from the right 

(Ignoruj ​​+1 zarówno jeśli chcesz dołączyć pojemnik zawierający m lub M - ale należy uważać, aby nie skończyć z ujemnymi wartościami pierwszy i ostatni)

teraz wiesz ile pojemniki na:

valid_edges = edges[first:-last] 
valid_perc = perc[first:-last] 

Wykluczy to pierwsze punkty: first i ostatnie punkty last.

Być może nie zwróciłem wystarczającej uwagi na zaokrąglanie i jest błąd "jeden po drugim", ale myślę, że pomysł jest dobry. :-)

Prawdopodobnie musisz złapać specjalne przypadki, takie jak M > edges[-1], ale dla czytelności nie uwzględniłem tych.


lub gdy pojemniki nie są równomiernie rozłożonych maski wykorzystanie Boolean zamiast obliczania:

first = edged[edges < m].size + 1 
last = edged[edges > M].size + 1