Почему «any» иногда работает намного быстрее, а иногда намного медленнее, чем «max» для логических значений в python? - PullRequest
1 голос
/ 30 апреля 2019

Рассмотрим следующий код:

import numpy as np
import pandas as pd
a = pd.DataFrame({'case': np.arange(10000) % 100,
                  'x': np.random.rand(10000) > 0.5})
%timeit any(a.x)
%timeit a.x.max()
%timeit a.groupby('case').x.transform(any)
%timeit a.groupby('case').x.transform(max)

13.2 µs ± 179 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
195 µs ± 811 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
25.9 ms ± 555 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
1.43 ms ± 13.1 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

b = pd.DataFrame({'x': np.random.rand(100) > 0.5})
%timeit any(b.x)
%timeit b.x.max()

13.1 µs ± 205 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
81.5 µs ± 1.81 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)

Мы видим, что «any» работает быстрее, чем «max» в булевых пандах. Серии размером 100 и 10000, но когда мы пытаемся сгруппировать и преобразовать данные в группы по 100, внезапно «max» оказывается намного быстрее, чем "любой". Зачем?

Ответы [ 2 ]

2 голосов
/ 30 апреля 2019

Потому что any оценка ленива. Это означает, что функция any остановится на первом логическом элементе True.

Однако max не может этого сделать, потому что требуется проверить каждый элемент в последовательности, чтобы убедиться, что он не пропустил ни одного большего элемента.

Именно поэтому max всегда будет проверять все элементы, когда any проверяет только элементы перед первым True.

Случай, когда max работает быстрее, это, вероятно, случаи с приведением типов, потому что все значения в numpy хранятся в своих собственных типах и форматах, математические операции могут быть быстрее, чем any.

в Python.
0 голосов
/ 20 июня 2019

Как сказано в комментарии, функция Python any имеет механизм короткого замыкания, а np.any - нет.см здесь .

Но True in a.x еще быстрее:

 %timeit any(a.x)
53.6 µs ± 543 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)

%timeit True in (a.x)
3.39 µs ± 31.8 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...