2013-02-19 16 views
6

Ho un elenco di valori e un elenco di bordi del raccoglitore. Ora ho bisogno di verificare tutti i valori su quale bin appartengono. C'è un modo più divinatorio di iterare su dei valori e poi sopra i bidoni e controllando se il valore appartiene allo scomparto corrente, come:Python: Verifica a quale binario appartiene un valore

my_list = [3,2,56,4,32,4,7,88,4,3,4] 
bins = [0,20,40,60,80,100] 

for i in my_list: 
    for j in range(len(bins)): 
     if bins(j) < i < bins(j+1): 
      DO SOMETHING 

Questo non sembra molto bello per me. Grazie!

+0

Inizia ordinando la lista. –

risposta

14

probabilmente è troppo tardi, ma per riferimento futuro, NumPy ha una funzione che fa proprio questo:

http://docs.scipy.org/doc/numpy/reference/generated/numpy.digitize.html

>>> my_list = [3,2,56,4,32,4,7,88,4,3,4] 
>>> bins = [0,20,40,60,80,100] 
>>> np.digitize(my_list,bins) 
array([1, 1, 3, 1, 2, 1, 1, 5, 1, 1, 1]) 

Il risultato è una serie di indici che corrispondono al bidone da appartiene anche a tutti gli elementi di my_list. Si noti che la funzione valori anche bin che non rientrano il cognome, bordi bin:

>>> my_list = [-5,200] 
>>> np.digitize(my_list,bins) 
array([0, 6]) 

e panda ha qualcosa come troppo:

http://pandas.pydata.org/pandas-docs/dev/basics.html#discretization-and-quantiling

>>> pd.cut(my_list, bins) 
Categorical: 
array(['(0, 20]', '(0, 20]', '(40, 60]', '(0, 20]', '(20, 40]', '(0, 20]', 
     '(0, 20]', '(80, 100]', '(0, 20]', '(0, 20]', '(0, 20]'], dtype=object) 
Levels (5): Index(['(0, 20]', '(20, 40]', '(40, 60]', '(60, 80]', 
        '(80, 100]'], dtype=object) 
2

Forse questo vi aiuterà a ottenere sulla strada giusta:

>>> import itertools 
>>> my_list = [3,2,56,4,32,4,7,88,4,3,4] 
>>> for k, g in itertools.groupby(sorted(my_list), lambda x: x // 20 * 20): 
...  print k, list(g) 
... 
0 [2, 3, 3, 4, 4, 4, 4, 7] 
20 [32] 
40 [56] 
80 [88] 
+0

Chiedersi perché il voto negativo. – sberry

3

Prima di tutto, il codice sta per fallire in casi in cui il valore è pari a un confine bin -

cambiamento

if bins(j) < i < bins(j+1): 

per avere un segno <= da qualche parte.

Dopo di che, utilizzare il modulo bisect

import bisect 
bisect.bisect(x, bins) 

o bisect.bisect_right

a seconda se si preferisce prendere il bidone superiore o inferiore quando un valore è sul confine bin.

+1

Penso che gli argomenti di "bisect" siano invertiti. – sberry

Problemi correlati