First Python list index greater than x?
next(x[0] for x in enumerate(L) if x[1] > 0.7)
Find the indices of elements greater than x
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]
Finding list indexes of numbers greater than a value
You can simply iterate through the list and break when you condition is true:
test_list = [1,5,7,11,20,26,89]
for i, value in enumerate(test_list):
if value > 13:
break
print(value) # 20
print(i) # 4
In Python, how do you find the index of the first value greater than a threshold in a sorted list?
Have a look at bisect.
import bisect
l = [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
bisect.bisect(l, 55) # returns 7
Compare it with linear search:timeit bisect.bisect(l, 55)
# 375ns
timeit next((i for i,n in enumerate(l) if n > 55), len(l))
# 2.24us
timeit next((l.index(n) for n in l if n > 55), len(l))
# 1.93us
Efficient solution to find list indices greater than elements in a second list
So I found there is a numpy function to perform this task, np.searchsorted. which is much faster than the use of list comprehensions.
result=np.searchsorted(searchlist,newindices)
These are the timings for the various solutions:1. Standard List comprehension:
this was my first attempt at a solution
python3 -m timeit -s "import numpy as np" -s "import bisect" -s "h=np.sort(np.random.uniform(size=10000))" -s "n=np.sort(np.random.uniform(size=1000))" "r=[bisect.bisect_left(h,i) for i in n]"
200 loops, best of 5: 1.61 msec per loop2. Shortened search in for loop
This was the solution kindly provided by @lenik
python3 -m timeit -s "import numpy as np" -s "import bisect" -s "h=np.sort(np.random.uniform(size=10000))" -s "n=np.sort(np.random.uniform(size=1000))" "r=[bisect.bisect_left(h,n[0])]" "for i in n[1:]:" " r.append(bisect.bisect_left(h,i,r[-1]))"
200 loops, best of 5: 1.6 msec per loopHardly different from the list comprehension which I was somewhat surprised about...
3. Numpy searchsorted
python3 -m timeit -s "import numpy as np" -s "import bisect" -s "h=np.sort(np.random.uniform(size=10000))" -s "n=np.sort(np.random.uniform(size=1000))" "r=np.searchsorted(h,n)"
10000 loops, best of 5: 33.6 usec per loopApproximately 50 times faster than the list comprehension based solutions for this example, so hands down the fastest.
First pandas DataFrame column index greater than x
You want to check both if any value in the dataframe is greater than the given value, and also return the first value that satsfies the condition. You have idxmax
for that:
def first_greater(df, n, col):
m = df.col.ge(n)
return m.any() and m.idxmax()
Note that in the return statement, the right part of the
and
is only evaluated if the first condition m.any()
is satisfied, otherwise False
is returned.Let's check with the proposed examples:
first_greater(df, 5, 'col1')
# 0
first_greater(df, 7, 'col1')
# 5
first_greater(df, 4, 'col1')
# 2
first_greater(df, 6, 'col1')
# 2
first_greater(df, 22, 'col1')
# False
Input data -
col1
0 1
1 -5
2 6
3 4
4 -7
5 12
6 -2
7 0
8 -3
Counting the pairs in a list such that their first index is less than the second but the first element is greater than the second
Mergesort should be able to do this in O(nlogn).
During the merge process, when we have to merge the left and the right array, we compare the first elements of both the arrays, if first element of the right array is less than the current first array of the left array, pop it, add it to a new temp array. Also increment the counter by the length of the left array (since all the elements in the left array are greater but have a smaller index).
def mergeSort(a):
if len(a) >= 2:
mid = len(a)//2
left, right = mergeSort(a[:mid]), mergeSort(a[mid:])
temp = []
i, j = 0, 0
for _ in range(len(a)):
if i < len(left) and j < len(right):
if right[j] < left[i]:
temp.append(right[j])
# here we are counting are our pairs
counter[0] += len(left)-i
j += 1
else:
temp.append(left[i])
i += 1
elif i < len(left):
temp.append(left[i])
i += 1
else:
temp.append(right[j])
j += 1
return temp
else:
return a
counter = [0]
arr = [5, 2, 10, 9, 7]
mergeSort(arr)
print(counter[0])
Related Topics
Slicing a List into N Nearly-Equal-Length Partitions
Improve Current Implementation of a Setinterval
How to Download a File from Google Drive Using Python and the Drive API V3
Display Realtime Output of a Subprocess in a Tkinter Widget
Changing Image Hue with Python Pil
Method Not Allowed Flask Error 405
How to Use a Default Namespace in an Lxml Xpath Query
Why Does Numpy.Zeros Takes Up Little Space
Overflowerror: (34, 'Result Too Large')
Saving Plots (Axessubplot) Generated from Python Pandas with Matplotlib's Savefig
How to Obscure a Line Behind a Surface Plot in Matplotlib
How to Fix Selenium Webdriverexception: the Browser Appears to Have Exited Before We Could Connect
Pip: How to Install a Git Pull Request
Break the Function After Certain Time
Is It Better to Use "Is" or "==" for Number Comparison in Python
Pandas Expand Rows from List Data Available in Column
Python Regex to Find a String in Double Quotes Within a String
Numpy Array Dtype Is Coming as Int32 by Default in a Windows 10 64 Bit MAChine