2012-05-21 15 views
6

Voglio verificare se un NumPyArray contiene valori in un set e, in tal caso, impostare quell'area in un array = 1. Se non è impostato un keepRaster = 2.Verificare se i valori in un set sono in una matrice numpy in python

numpyArray = #some imported array 
repeatSet= ([3, 5, 6, 8]) 

confusedRaster = numpyArray[numpy.where(numpyArray in repeatSet)]= 1 

Resa:

<type 'exceptions.TypeError'>: unhashable type: 'numpy.ndarray' 

c'è un modo per eseguire un ciclo attraverso di essa?

for numpyArray 
     if numpyArray in repeatSet 
      confusedRaster = 1 
     else 
      keepRaster = 2 

Per chiarire e chiedere un ulteriore aiuto bit:

Quello che sto cercando di arrivare, e attualmente sto facendo, sta mettendo un ingresso raster in un array. Ho bisogno di leggere i valori nella matrice 2-d e creare un altro array basato su quei valori. Se il valore dell'array è in un set, il valore sarà 1. Se non è in un set, il valore sarà derivato da un altro input, ma per ora dirò 77. Questo è quello che sto attualmente usando. Il mio input di test ha circa 1500 righe e 3500 colonne. Si blocca sempre intorno fila 350.

for rowd in range(0, width): 
    for cold in range (0, height): 
     if numpyarray.item(rowd,cold) in repeatSet: 
      confusedArray[rowd][cold] = 1 
     else: 
      if numpyarray.item(rowd,cold) == 0: 
       confusedArray[rowd][cold] = 0 
      else: 
       confusedArray[rowd][cold] = 2 

risposta

12

Nelle versioni 1.4 e superiori, numpy fornisce la funzione in1d.

>>> test = np.array([0, 1, 2, 5, 0]) 
>>> states = [0, 2] 
>>> np.in1d(test, states) 
array([ True, False, True, False, True], dtype=bool) 

È possibile utilizzarlo come maschera per l'assegnazione.

>>> test[np.in1d(test, states)] = 1 
>>> test 
array([1, 1, 1, 5, 1]) 

Qui ci sono alcuni usi più sofisticati di sintassi indicizzazione e l'assegnazione di NumPy che penso si applicherà al vostro problema. Si noti l'uso di operatori bit a bit per sostituire if logica basata su:

>>> numpy_array = numpy.arange(9).reshape((3, 3)) 
>>> confused_array = numpy.arange(9).reshape((3, 3)) % 2 
>>> mask = numpy.in1d(numpy_array, repeat_set).reshape(numpy_array.shape) 
>>> mask 
array([[False, False, False], 
     [ True, False, True], 
     [ True, False, True]], dtype=bool) 
>>> ~mask 
array([[ True, True, True], 
     [False, True, False], 
     [False, True, False]], dtype=bool) 
>>> numpy_array == 0 
array([[ True, False, False], 
     [False, False, False], 
     [False, False, False]], dtype=bool) 
>>> numpy_array != 0 
array([[False, True, True], 
     [ True, True, True], 
     [ True, True, True]], dtype=bool) 
>>> confused_array[mask] = 1 
>>> confused_array[~mask & (numpy_array == 0)] = 0 
>>> confused_array[~mask & (numpy_array != 0)] = 2 
>>> confused_array 
array([[0, 2, 2], 
     [1, 2, 1], 
     [1, 2, 1]]) 

Un altro approccio sarebbe quello di utilizzare numpy.where, che crea un nuovo array, utilizzando i valori dal secondo argomento in cui mask è vero, e valori dal terzo argomento in cui mask è falso. (Come con assegnazione, l'argomento può essere uno scalare o un array nella stessa forma mask.) Questo potrebbe essere un po 'più efficiente di quanto sopra, ed è certamente più concisa:

>>> numpy.where(mask, 1, numpy.where(numpy_array == 0, 0, 2)) 
array([[0, 2, 2], 
     [1, 2, 1], 
     [1, 2, 1]]) 
+0

Hmm, così come capire che. Se il valore del test è nella lista degli stati di True, che sarà = 1, altrimenti sarà uguale a quello che era. C'è un modo per rendere l'output array ([1,0,1,0,0]) – mkmitchell

+0

@mkmitchell, sì, hai capito. È in qualche modo simile all'assegnazione delle sezioni con normali elenchi Python, ma a) utilizza il sistema di indicizzazione più complesso di numpy e b) segue la convenzione numpy che l'assegnazione di uno scalare a una porzione di un array assegna tutti i valori della sezione a quel valore scalare. – senderle

+0

Che ne dici se si tratta di un array 2-D? – mkmitchell

1

Ecco un possibile modo di fare ciò che si whant:

numpyArray = np.array([1, 8, 35, 343, 23, 3, 8]) # could be n-Dimensional array 
repeatSet = np.array([3, 5, 6, 8]) 
mask = (numpyArray[...,None] == repeatSet[None,...]).any(axis=-1) 
print mask 
>>> [False True False False False True True] 
Problemi correlati