2014-09-03 15 views
7

E 'possibile convertire una matrice di indici in una matrice di uni e zeri, dato l'intervallo? cioè [2,3] -> [0, 0, 1, 1, 0], nella gamma di 5Come si può trasformare un array di indici in un array di maschere in Numpy?

Sto cercando di automatizzare qualcosa di simile:

>>> index_array = np.arange(200,300) 
array([200, 201, ... , 299]) 

>>> mask_array = ???   # some function of index_array and 500 
array([0, 0, 0, ..., 1, 1, 1, ... , 0, 0, 0]) 

>>> train(data[mask_array]) # trains with 200~299 
>>> predict(data[~mask_array]) # predicts with 0~199, 300~499 
+0

scipy ha un modulo matrice mascherato. È legato alla domanda. http://docs.scipy.org/doc/numpy/reference/maskedarray.html –

+0

'[x in array_indice per x nell'intervallo (500)]' un po 'lo fa, ma con 'True' e' False' invece di 1 e 0. – genisage

+0

@genisage Puoi fare il tuo commento come risposta? Voglio scegliere il tuo. È la cosa esatta che stavo cercando. Grazie per la risposta! – Efreeto

risposta

15

Ecco un modo:

In [1]: index_array = np.array([3, 4, 7, 9]) 

In [2]: n = 15 

In [3]: mask_array = np.zeros(n, dtype=int) 

In [4]: mask_array[index_array] = 1 

In [5]: mask_array 
Out[5]: array([0, 0, 0, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0]) 

Se la maschera è sempre un intervallo, è possibile eliminare index_array, e assegnare 1 ad una fetta:

In [6]: mask_array = np.zeros(n, dtype=int) 

In [7]: mask_array[5:10] = 1 

In [8]: mask_array 
Out[8]: array([0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0]) 

Se si desidera un array di valori booleani, invece di interi, modificare il dtype di mask_array al momento della creazione:

In [11]: mask_array = np.zeros(n, dtype=bool) 

In [12]: mask_array 
Out[12]: 
array([False, False, False, False, False, False, False, False, False, 
     False, False, False, False, False, False], dtype=bool) 

In [13]: mask_array[5:10] = True 

In [14]: mask_array 
Out[14]: 
array([False, False, False, False, False, True, True, True, True, 
     True, False, False, False, False, False], dtype=bool) 
+0

+1 Questa è anche una bella risposta, specialmente se qualcuno vuole che mask_array sia un np.array. – Efreeto

+0

Ed è molto più efficiente della comprensione delle liste. – JulienD

+0

C'è qualche vantaggio nell'usare int invece di bool? Mi sto solo chiedendo perché la parte superiore della risposta non consigli a Bool quando la domanda è chiedere una maschera. – Annan

-1

Come richiesto, qui è in una risposta. Il codice:

[x in index_array for x in range(500)] 

vi darà una maschera come avete chiesto, ma userà Bools invece di 0 e di 1.

+0

Per favore non dargli un voto più basso. Ho chiesto a lui/lei di rendere il suo commento come una risposta. E cambierò la risposta accettata in modo che questa risposta non venga downvoted. – Efreeto

2

Per una sola dimensione, provare:

n = (15,) 
index_array = [2, 5, 7] 
mask_array = numpy.zeros(n) 
mask_array[index_array] = 1 

Per più di una dimensione, convertire i vostri indici n-dimensionali in quelle unidimensionali, quindi utilizzare Ravel:

n = (15, 15) 
index_array = [[1, 4, 6], [10, 11, 2]] # you may need to transpose your indices! 
mask_array = numpy.zeros(n) 
flat_index_array = np.ravel_multi_index(
    index_array, 
    mask_array.shape) 
numpy.ravel(mask_array)[flat_index_array] = 1 
0

C'è una bella trucco per fare questo come one-liner, usare le funzioni numpy.in1d e numpy.arange come questa (la linea finale è la parte chiave):

>>> x = np.linspace(-2, 2, 10) 
>>> y = x**2 - 1 
>>> idxs = np.where(y<0) 

>>> np.in1d(np.arange(len(x)), idxs) 
array([False, False, False, True, True, True, True, False, False, False], dtype=bool) 

Il lato negativo di questo approccio è che è ~ 10-100x più lento dell'approprio Warren Weckesser ha dato ... ma è un one-liner, che può o non può essere quello che stai cercando.

Problemi correlati