2012-03-27 15 views
5

Esiste una funzione incorporata in Python3/Numpy che filtra una matrice e restituisce gli indici degli elementi che rimangono? Qualcosa di simile a numpy.argsort per l'ordinamento. Il filtro che ho sta impostando entrambe le soglie min e max - tutti i valori sotto/sopra min/max devono essere filtrati.Filtra una matrice in Python3/Numpy e restituisce gli indici

Ho visto la funzione di Python filter, ma non vedo un modo per estrarre gli indici che lo utilizzano.

MODIFICA: Un sacco di informazioni utili nelle risposte, grazie!

Come @SvenMarnach ha sottolineato, la maschera è sufficiente:

mask = (min_value < a) & (a < max_value) 

Ora devo applicare questa maschera per altri array della stessa forma a, ma non è sicuro che cosa è il modo migliore per farlo. ..

risposta

4

È possibile ottenere gli indici degli elementi nella matrice unidimensionale a che sono maggiori di min_value e Les rispetto max_value con

indices = ((min_value < a) & (a < max_value)).nonzero()[0] 

Di solito non hanno bisogno di tali indici, però, ma si può lavorare in modo più efficiente con la maschera

mask = (min_value < a) & (a < max_value) 

Questa maschera è un array booleano con la stessa forma a.

Edit: Se si dispone di una matrice b della stessa forma come a, è possibile estrarre gli elementi di b corrispondenti alle True voci in mask con

b[mask] 
+0

Ottimo! Grazie per una rapida risposta. In effetti, la maschera è sufficiente - ma come faccio ad applicare questa maschera ad un altro array della stessa forma di 'a'? – Katya

+0

@ Katya cosa significherebbe? Se avessi un array 5x5 con una maschera particolare, potresti definire cosa significherebbe applicare su un array 4x3 o 6x6? – Hooked

+0

@ Katya: cosa intendi con "applicare questa maschera"? Estrai gli elementi corrispondenti? Ho aggiunto una frase alla mia risposta a tal fine. –

4

Il comando numpy.wherewill return the indices of an array dopo' Ho applicato una maschera su di loro. Per esempio:

import numpy as np 
A = np.array([1,2,3,6,2]) 
np.where(A>2) 

dà:

(array([2, 3]),) 

Un esempio più complesso:

A = np.arange(27).reshape(3,3,3) 
np.where((A>10) & (A<15)) 

dà:

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

Sono d'accordo con @SvenMarnach, di solito si non ne ed gli indici.

+0

Avevo appena creato la mia versione di 'where' quando l'ho vista. Sospiro. – senderle

+0

@senderle è probabilmente anche più lento. Ogni volta che penso di conoscere il pieno potere di 'numpy/scipy', questo sito mi mostra che mi sbaglio. – Hooked

1

Mi piace molto la risposta di Sven, e infatti, numpy.where fa esattamente quello che vuoi, come mi ha ricordato Hooked. Ma soprattutto perché l'ho già scritto, ecco un altro approccio, solo per illustrare alcuni trucchi.my_filter può essere qualsiasi funzione che restituisce una matrice booleana della stessa forma come input:

def my_filter(a): 
    return (10 < a) & (a < 40) 

a_mask = my_filter(a) 
indices = [ind[a_mask] for ind in numpy.indices(a.shape)] 

Ad esempio:

>>> a = numpy.arange(100).reshape((10, 10)) 
>>> def my_filter(a): 
...  return (min_value < a) & (a < max_value) 
... 
>>> a_mask = my_filter(a) 
>>> [ind[a_mask] for ind in numpy.indices(a.shape)] 
[array([1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 
     3, 3, 3, 3, 3, 3]), 
array([1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 
     4, 5, 6, 7, 8, 9])] 
4

Non direttamente correlata alla sua domanda, ma filter() fa parte di un insieme di tre funzioni, map(), filter() e reduce(), che consentono l'elaborazione di elenchi in stile funzionale in Python.

  • map(mapping_function, input_list) prende in una funzione di un argomento e una lista, si applica la funzione di ciascun elemento della lista a sua volta, e restituisce una lista di output come risultato. È più o meno equivalente alla comprensione della lista [mapping_function(item) for item in input_list].

  • filter(filter_function, input_list) restituisce un elenco di elementi da input_list per i quali il filter_function restituiti True. L'equivalente di comprensione della lista è [item for item in items if filter_function(item)].

  • reduce(combining_function, input_list) combina ripetutamente coppie adiacenti di elementi nell'elenco di input fino a quando non viene lasciato un solo valore. Ad esempio la somma di un elenco di numeri potrebbe essere espressa come reduce(operator.add, numbers).

La funzionalità di map() e filter() è fornita da list comprehension in Python (che è il motivo per cui i map e filter funzioni non vengono utilizzate molto spesso.)

reduce() è una di quelle cose che doesn' Si suggerisce come risposta intuitiva a ... qualsiasi cosa. È quasi sempre più chiaro scrivere un ciclo, il che spiega perché non lo vedi spesso.