Find the indices of elements greater than x
Question:
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!
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]
>>> 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])
using filter built-in function is fine
>>>a = [1, 2, 3, 4, 5, 6, 7, 8, 9]
>>>filter(lambda x : x < 4, a)
[1, 2, 3]
Explanation
filter(FUN, Iterable)
this expression will iterate all element from Iterable and supply to FUN function as argument, if return is True ,then the arugment will be append to a internal list
lambda x: x > 4
this means a anonymous function that will take a argument and test it if bigger than 4, and return True of False value
Your solution
if you are try to delete all elements larger than 4 ,then try blow
>>> a = [1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> filter(lambda x: x<4 ,a)
[1, 2, 3]
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]
The simplest in my eyes would be to use numpy
X[np.array(a)>4]#X needs to be np.array as well
Explanation:
np.array converts a to an array.
np.array(a)>4 gives a bool array with all the elements that should be kept
And X is filtered by the bool array so only the elements where a is greater than 4 are selected (and the rest discarded)
I guess I came here a bit late (while things got easier using Numpy)..
import numpy as np
# Create your array
a = np.arange(1, 10)
# a = array([1, 2, 3, 4, 5, 6, 7, 8, 9])
# Get the indexes/indices of elements greater than 4
idx = np.where(a > 4)[0]
# idx = array([4, 5, 6, 7, 8])
# Get the elements of the array that are greater than 4
elts = a[a > 4]
# elts = array([5, 6, 7, 8, 9])
# Convert idx(or elts) to a list
idx = list(idx)
#idx = [4, 5, 6, 7, 8]
looping is slow, using divide and conquer method. code in C++
// find index whose value is equal to or greater than "key" in an ordered vector.
// note: index may be equal to indices.size()
size_t StartIndex(const std::vector<int>& indices, int key)
{
if (indices.empty() || key <= indices[0])
return 0;
if (key > indices.back())
return indices.size();
size_t st = 0;
size_t end = indices.size() - 1;
while (true)
{
if ((end - st) < 2)
return (indices[st] < key) ? end : st;
size_t mid = ((st + end) >> 1); // (st + end) / 2
if (indices[mid] == key)
return mid;
(indices[mid] < key ? st : end) = mid;
}
}
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!
>>> [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]
>>> 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])
using filter built-in function is fine
>>>a = [1, 2, 3, 4, 5, 6, 7, 8, 9]
>>>filter(lambda x : x < 4, a)
[1, 2, 3]
Explanation
filter(FUN, Iterable)
this expression will iterate all element from Iterable and supply to FUN function as argument, if return is True ,then the arugment will be append to a internal list
lambda x: x > 4
this means a anonymous function that will take a argument and test it if bigger than 4, and return True of False value
Your solution
if you are try to delete all elements larger than 4 ,then try blow
>>> a = [1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> filter(lambda x: x<4 ,a)
[1, 2, 3]
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]
The simplest in my eyes would be to use numpy
X[np.array(a)>4]#X needs to be np.array as well
Explanation:
np.array converts a to an array.
np.array(a)>4 gives a bool array with all the elements that should be kept
And X is filtered by the bool array so only the elements where a is greater than 4 are selected (and the rest discarded)
I guess I came here a bit late (while things got easier using Numpy)..
import numpy as np
# Create your array
a = np.arange(1, 10)
# a = array([1, 2, 3, 4, 5, 6, 7, 8, 9])
# Get the indexes/indices of elements greater than 4
idx = np.where(a > 4)[0]
# idx = array([4, 5, 6, 7, 8])
# Get the elements of the array that are greater than 4
elts = a[a > 4]
# elts = array([5, 6, 7, 8, 9])
# Convert idx(or elts) to a list
idx = list(idx)
#idx = [4, 5, 6, 7, 8]
looping is slow, using divide and conquer method. code in C++
// find index whose value is equal to or greater than "key" in an ordered vector.
// note: index may be equal to indices.size()
size_t StartIndex(const std::vector<int>& indices, int key)
{
if (indices.empty() || key <= indices[0])
return 0;
if (key > indices.back())
return indices.size();
size_t st = 0;
size_t end = indices.size() - 1;
while (true)
{
if ((end - st) < 2)
return (indices[st] < key) ? end : st;
size_t mid = ((st + end) >> 1); // (st + end) / 2
if (indices[mid] == key)
return mid;
(indices[mid] < key ? st : end) = mid;
}
}