2015-09-01 11 views
10

Sto cercando un modo per binarizzare l'array N-d numerico basato sulla soglia utilizzando solo un'espressione. Così ho qualcosa di simile:Binarizzazione della matrice Numpy usando una sola espressione

np.random.seed(0) 
np.set_printoptions(precision=3) 
a = np.random.rand(4, 4) 
threshold, upper, lower = 0.5, 1, 0 

un 'ora:

array([[ 0.02 , 0.833, 0.778, 0.87 ], 
     [ 0.979, 0.799, 0.461, 0.781], 
     [ 0.118, 0.64 , 0.143, 0.945], 
     [ 0.522, 0.415, 0.265, 0.774]]) 

Ora posso licenziare queste 2 espressioni:

a[a>threshold] = upper 
a[a<=threshold] = lower 

e raggiungere ciò che voglio:

array([[ 0., 1., 1., 1.], 
     [ 1., 1., 0., 1.], 
     [ 0., 1., 0., 1.], 
     [ 1., 0., 0., 1.]]) 

Ma c'è un modo per farlo con solo Espressione?

risposta

14

Possiamo considerare np.where:

np.where(a>threshold, upper, lower) 
Out[6]: 
array([[0, 1, 1, 1], 
     [1, 1, 0, 1], 
     [0, 1, 0, 1], 
     [1, 0, 0, 1]]) 
2

si può scrivere espressione direttamente, esso restituisce una matrice booleana, e può essere utilizzato semplicemente come un intero 1 byte senza segno ("uint8") array per ulteriori calcoli:

print a > 0.5 

uscita

[[False True True True] 
[ True True False True] 
[False True False True] 
[ True False False True]] 

In una riga e personalizzati superiori/valori inferiori si può scrivere così per esempio:

upper = 10 
lower = 3 
treshold = 0.5 

print lower + (a>treshold) * (upper-lower) 
3

Numpy tratta ogni matrice 1d come vettore, matrice 2D come sequenza di vettori (matrice) e 3d + matrice come tensore generico. Ciò significa che quando eseguiamo operazioni, stiamo eseguendo la matematica vettoriale. Quindi, solo si può fare:

>>> a = (a > 0.5).astype(np.int_) 

Ad esempio:

>>> np.random.seed(0) 
>>> np.set_printoptions(precision=3) 

>>> a = np.random.rand(4, 4) 

>>> a 
>>> array([[ 0.549, 0.715, 0.603, 0.545], 
     [ 0.424, 0.646, 0.438, 0.892], 
     [ 0.964, 0.383, 0.792, 0.529], 
     [ 0.568, 0.926, 0.071, 0.087]]) 

>>> a = (a > 0.5).astype(np.int_) # Where the numpy magic happens. 

>>> array([[1, 1, 1, 1], 
      [0, 1, 0, 1], 
      [1, 0, 1, 1], 
      [1, 1, 0, 0]]) 

cosa succede qui è che si sta iterazione automaticamente attraverso ogni elemento di ogni riga della matrice 4x4 e l'applicazione di un confronto booleano ad ogni elemento.

Se> 0,5 restituisce True, altrimenti restituisce False.

Poi chiamando il metodo .astype e passando np.int_ come argomento, che stai dicendo NumPy per sostituire tutti i valori booleani con la loro rappresentazione intera, in effetti binarizing la matrice in base al valore di confronto.

1

Un metodo più breve è semplicemente moltiplicare la matrice booleana dalla condizione di 1 o 1.0, a seconda del tipo desiderato.

>>> a = np.random.rand(4,4) 
>>> a 
array([[ 0.63227032, 0.18262573, 0.21241511, 0.95181594], 
     [ 0.79215808, 0.63868395, 0.41706148, 0.9153959 ], 
     [ 0.41812268, 0.70905987, 0.54946947, 0.51690887], 
     [ 0.83693151, 0.10929998, 0.19219377, 0.82919761]]) 
>>> (a>0.5)*1 
array([[1, 0, 0, 1], 
     [1, 1, 0, 1], 
     [0, 1, 1, 1], 
     [1, 0, 0, 1]]) 
>>> (a>0.5)*1.0 
array([[ 1., 0., 0., 1.], 
     [ 1., 1., 0., 1.], 
     [ 0., 1., 1., 1.], 
     [ 1., 0., 0., 1.]]) 
Problemi correlati