Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Find the indices of elements greater than x

Given the following vector,

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

I need to identify the indices of "a" whose elements are >= than 4, like this:

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

The info in "idx" will be used to delete the elements from another list X (X has the same number of elements that "a"):

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

I heard that numpy might help. Any ideas? Thanks!

like image 879
Oliver Amundsen Avatar asked Dec 05 '12 06:12

Oliver Amundsen


2 Answers

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

enumerate returns the index and value of each item in an array. So if the value v is greater than 4, include the index i in the new array.

Or you can just modify your list in place and exclude all values above 4.

>>> a[:] = [x for x in a if x<=4] >>> a  [1, 2, 3, 4] 
like image 154
Aesthete Avatar answered Sep 18 '22 05:09

Aesthete


OK, I understand what you mean and a Single line of Python will be enough:

using list comprehension

[ 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'] 

Zip function will return a list of tuples

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

List comprehension is a shortcut to loop an element over list which after "in", and evaluate the element with expression, then return the result to a list, also you can add condition on which result you want to return

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

This code does nothing but return all pairs that zipped up.

>>> [(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')] 

What we do is to add a condition on it by specify "if" follow by a boolean expression

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

using 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 

Use itertools.compress with single line in Python to finish close this task

>>> 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'] 

Explanation for itertools.compress, I think this will be clear for your understanding:

>>> [ _ for _ in itertools.compress([1,2,3,4,5],[False,True,True,False,True]) ] [2, 3, 5] 
like image 39
Shawn Zhang Avatar answered Sep 19 '22 05:09

Shawn Zhang