Предположим, что у меня есть отсортированный массив кортежей, который сортируется по первому значению. Я хочу найти первый индекс, где выполняется условие для первого элемента кортежа. например, как заменить следующий код
test_array = [(1,2),(3,4),(5,6),(7,8),)(9,10)]
min_value = 5
index = 0
for c in test_array:
if c[0] > min_value:
break
else:
index = index + 1
С эквивалентом поиска в Matlab?
то есть. В конце этого цикла я ожидаю получить 3, но я хотел бы сделать это более эффективным. Я прекрасно использую numpy для этого. Я пробовал использовать argmax, но безрезультатно.
Спасибо
Поскольку список сортируется, и если вы знаете максимальное возможное значение для второго элемента (или может быть только один элемент с тем же самым первым значением), вы можете применить bisect
в списке кортежей (возвращает сортировка позиции в списке)
import bisect
test_array = [(1,2),(3,4),(5,6),(7,8),(9,10)]
min_value = 5
print(bisect.bisect_left(test_array,(min_value,10000)))
Hardcoding to 10000 плохой, поэтому, если у вас есть только целые числа, вы можете сделать это:
print(bisect.bisect_left(test_array,(min_value+1,)))
результат: 3
Если у вас есть floats (также работает с целыми числами), вы можете использовать sys.float_info.epsilon
следующим образом:
print(bisect.bisect_left(test_array,(min_value*(1+sys.float_info.epsilon),)))
Он имеет сложность O(log(n))
, поэтому он намного лучше, чем простой цикл for
, когда есть много элементов.
В общем случае numpy where
используется по типу, аналогичному MATLAB find
. Однако с точки зрения эффективности я where
нельзя управлять, чтобы вернуть только первый найденный элемент. Итак, с вычислительной точки зрения, то, что вы здесь делаете, не является менее менее эффективным.
эквивалентом where
будет
index = numpy.where(numpy.array([t[0] for t in test_array]) >= min_value)
index = index[0] - 1
Вы можете использовать numpy для указания элементов, которые подчиняются условиям, а затем использовать argmax()
, чтобы получить индекс первого
import numpy
test_array = numpy.array([(1,2),(3,4),(5,6),(7,8),(9,10)])
min_value = 5
print (test_array[:,0]>min_value).argmax()
если вы хотите найти все элементы, удовлетворяющие условию, использование может заменить argmax()
на nonzero()[0]