Заменить цикл в Python на эквивалент поиска в Matlab

Предположим, у меня есть отсортированный массив кортежей, который отсортирован по первому значению. Я хочу найти первый индекс, где выполняется условие для первого элемента кортежа. т.е. как мне заменить следующий код

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, но безрезультатно.

Спасибо

3 ответа

Решение

Поскольку список отсортирован, и если вы знаете максимально возможное значение для второго элемента (или если может быть только 1 элемент с таким же первым значением), вы можете применить 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)))

Жесткое кодирование до 10000 плохо, поэтому, если у вас есть только целые числа, вы можете сделать это вместо этого:

print(bisect.bisect_left(test_array,(min_value+1,)))

результат: 3

если у вас есть числа с плавающей точкой (также работает с целыми числами), вы можете использовать sys.float_info.epsilon как это:

print(bisect.bisect_left(test_array,(min_value*(1+sys.float_info.epsilon),)))

Она имеет O(log(n)) сложность, так что это гораздо лучше, чем простой for цикл, когда много элементов.

Вы можете использовать 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]

В общем, нампи where используется аналогично MATLAB find, Однако с точки зрения эффективности я where невозможно контролировать, чтобы вернуть только первый найденный элемент. Итак, с вычислительной точки зрения, то, что вы здесь делаете, не менее неэффективно.

where эквивалент будет

index = numpy.where(numpy.array([t[0] for t in test_array]) >= min_value)
index = index[0] - 1
Другие вопросы по тегам