Почему «логическое индексирование» NumPy здесь медленнее, чем «фильтр» - PullRequest
0 голосов
/ 14 февраля 2020

У меня есть вопрос, касающийся скорости булевой индексации NumPy: я ожидал, что она будет быстрее, чем метод регулярной фильтрации питонов. Я использовал это неправильно? Заранее спасибо за помощь!

L = np.arange(499999, 1000000) 
index = (L % 6 == 1) | (L % 3 != 1)
L = L[index]
#9.53 ms ± 370 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

L = range(499999, 1000000)
L = filter(lambda x:(x % 6 == 1) or (x%3 != 1), L)
#338 ns ± 1.13 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each) much much faster!!!

L = [x for x in range(499999, 1000000) if (x % 6 == 1) or (x%3 != 1)]
#51.5 ms ± 1.7 ms per loop (mean ± std. dev. of 7 runs, 10 loops each) I expected this to be faster too!?

1 Ответ

3 голосов
/ 14 февраля 2020

In , filter является ленивым . Это означает, что если вы позвоните filter(lambda x:(x % 6 == 1) or (x%3 != 1), L), он не будет ничего делать . Он просто создаст filter объект, но не отфильтрует итерируемое вообще.

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

Итак, построение a filter выполняется за постоянное время. Однако если вы используете что-то вроде list(..), которое материализует список, мы получим за 10 прогонов:

>>> timeit(lambda: list(filter(lambda x:(x % 6 == 1) or (x%3 != 1), L)), number=10)
2.855049993000648

, поэтому в среднем для фильтрации всего списка требуется 0,2855 секунд L.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...