2012-12-05 11 views
13

Dato il vettore seguente,Trova gli indici di elementi maggiori di x

a = [1, 2, 3, 4, 5, 6, 7, 8, 9] 

devo identificare gli indici di "a" i cui elementi sono> = a 4, in questo modo:

idx = [3, 4, 5, 6, 7, 8] 

le informazioni contenute in "idx" verrà utilizzato per eliminare gli elementi di un altro elenco X (X ha lo stesso numero di elementi che "a"):

del X[idx] #idx is used to delete these elements in X. But so far isn't working. 

i h eard che numpy potrebbe aiutare. Qualche idea? Grazie!

+0

i loop sono un buon punto di partenza. – monkut

+0

L'esempio 'idx' è errato, ci sono solo ** 9 elementi ** nell'elenco e quindi ** 9 indici, 0-8 **. – Aesthete

+0

La tua domanda è leggermente in contraddizione con se stessa. Sembra che potresti avere indici confusi con elementi (il tuo 'idx' in effetti è una lista di elementi e stai chiedendo un elenco di indici). Inoltre, per favore, dì cosa hai provato da solo prima di chiedere? – 0xc0de

risposta

11

OK, capisco quello che vuoi dire e una linea singola di Python sarà sufficiente:

usando di lista

[ j for (i,j) in zip(a,x) if i >= 4 ] 
# a will be the list compare to 4 
# x another list with same length 

Explanation: 
>>> a 
[1, 2, 3, 4, 5, 6, 7, 8, 9] 
>>> x 
['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'j'] 

funzione Zip restituirà una lista di tuple

>>> zip(a,x) 
[(1, 'a'), (2, 'b'), (3, 'c'), (4, 'd'), (5, 'e'), (6, 'f'), (7, 'g'), (8, 'h'), (9, 'j')] 

La comprensione degli elenchi è una scorciatoia per eseguire il ciclo di un elemento sulla lista che dopo "in", e valutare l'elemento con espressione, quindi restituire il risultato in un elenco, inoltre è possibile aggiungere la condizione su cui si desidera restituire il risultato

>>> [expression(element) for **element** in **list** if condition ] 

Questo codice non fa altro che restituire tutte le coppie chiuse.

>>> [(i,j) for (i,j) in zip(a,x)] 
[(1, 'a'), (2, 'b'), (3, 'c'), (4, 'd'), (5, 'e'), (6, 'f'), (7, 'g'), (8, 'h'), (9, 'j')] 

Quello che facciamo è quello di aggiungere una condizione su di esso per specificare "se" seguire da un'espressione booleana

>>> [(i,j) for (i,j) in zip(a,x) if i >= 4] 
[(4, 'd'), (5, 'e'), (6, 'f'), (7, 'g'), (8, 'h'), (9, 'j')] 

utilizzando itertools

>>> [ _ for _ in itertools.compress(d, map(lambda x: x>=4,a)) ] 
# a will be the list compare to 4 
# d another list with same length 

Usa itertools.compress con single line in Python per finire chiudi questa attività

>>> a = [1, 2, 3, 4, 5, 6, 7, 8, 9] 
>>> d = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'j'] # another list with same length 
>>> map(lambda x: x>=4, a) # this will return a boolean list 
[False, False, False, True, True, True, True, True, True] 


>>> import itertools 
>>> itertools.compress(d, map(lambda x: x>4, a)) # magic here ! 
<itertools.compress object at 0xa1a764c>  # compress will match pair from list a and the boolean list, if item in boolean list is true, then item in list a will be remain ,else will be dropped 
#below single line is enough to solve your problem 
>>> [ _ for _ in itertools.compress(d, map(lambda x: x>=4,a)) ] # iterate the result. 
['d', 'e', 'f', 'g', 'h', 'j'] 

Spiegazione per itertools.comprimere, credo che questo sarà chiaro per la vostra comprensione:

>>> [ _ for _ in itertools.compress([1,2,3,4,5],[False,True,True,False,True]) ] 
[2, 3, 5] 
+0

@OliverAmundsen questa sarà la mia soluzione finale –

+0

che ha funzionato! Grazie a @ShawnZhang. Potrebbe spiegare brevemente la logica dell '"uso della lista di comprensione"? grazie –

+0

@OliverAmundsen Ho aggiornato la mia risposta –

20
>>> [i for i,v in enumerate(a) if v > 4] 
[4, 5, 6, 7, 8] 

enumerate restituisce l'indice e il valore di ciascun elemento in un array. Quindi se il valore v è maggiore di 4, includere l'indice i nel nuovo array.

Oppure è possibile modificare l'elenco solo ed escludere tutti i valori sopra 4.

>>> a[:] = [x for x in a if x<=4] 
>>> a 
[1, 2, 3, 4] 
5
>>> import numpy as np 
>>> a = np.array(range(1,10)) 
>>> indices = [i for i,v in enumerate(a >= 4) if v] 
>>> indices 
[3, 4, 5, 6, 7, 8] 

>>> mask = a >= 4 
>>> mask 
array([False, False, False, True, True, True, True, True, True], dtype=boo 
l) 
>>> a[mask] 
array([4, 5, 6, 7, 8, 9]) 
>>> np.setdiff1d(a,a[mask]) 
array([1, 2, 3]) 
1

utilizzando funzione incorporata nel filtro è bene

>>>a = [1, 2, 3, 4, 5, 6, 7, 8, 9] 
>>>filter(lambda x : x < 4, a) 
[1, 2, 3] 

Spiegazione

filtro (FUN, Iterable)

questa espressione itererà tutti gli elementi da Iteratile e fornire la funzione FUN come argomento, se ritorno i è vero, allora l'arugment verrà aggiungere a un elenco interno

lambda x: x> 4

questo significa una funzione anonima che avrà un argomento e verificare se più grande di 4, e restituire vero o falso valore

La soluzione

se si sta tenta di eliminare tutti gli elementi più grandi di 4, quindi provare colpo

>>> a = [1, 2, 3, 4, 5, 6, 7, 8, 9] 
>>> filter(lambda x: x<4 ,a) 
[1, 2, 3] 
+0

E cosa succede quando chiami 'del a [9]'? – Aesthete

+1

-1. Stai restituendo gli elementi della lista, non gli indici. Anche se questo funziona per la lista data ma non è una risposta corretta. – 0xc0de

+0

@Astante lunghezza di a qui è 9, a [9] significa il decimo elemento di list.if del a [9], python genererà un errore di indice –

2

Il più semplice ai miei occhi potrebbe essere quella di utilizzare NumPy

X[np.array(a)>4]#X needs to be np.array as well 

Spiegazione: np.array converte un a un array.

np.array (a)> 4 fornisce una matrice bool con tutti gli elementi che devono essere tenuti

E X viene filtrato dai matrice bool modo che solo gli elementi dove a è superiore a 4 sono selezionati (e il resto scartato)

Problemi correlati