Подтвердить что ты не робот

Встроенный диапазон или numpy.arange: что более эффективно?

При повторении большого массива с выражением диапазона, следует ли использовать встроенную функцию диапазона Python или numpy arange, чтобы получить максимальную производительность?

Мои рассуждения до сих пор:

arange, вероятно, прибегает к собственной реализации и может быть быстрее. С другой стороны, arange возвращает полный массив, который занимает память, поэтому могут быть накладные расходы. Выражение диапазона Python 3 является генератором, который не сохраняет все значения в памяти.

4b9b3361

Ответ 1

Для больших массивов numpy должно быть более быстрым решением.

В numpy вы должны использовать комбинации векторизованных вычислений, ufuncs и indexing, чтобы решить ваши проблемы, так как он работает со скоростью C. Зацикливание по массивам numpy неэффективно по сравнению с этим.

(Что-то вроде худшего, что вы могли бы сделать, это перебрать массив с индексом, созданным с помощью range или np.arange, как предлагает первое предложение в вашем вопросе, но я не уверен, действительно ли вы имеете в виду что.)

import numpy as np
import sys

sys.version
# out: '2.7.3rc2 (default, Mar 22 2012, 04:35:15) \n[GCC 4.6.3]'
np.version.version
# out: '1.6.2'

size = int(1E6)

%timeit for x in range(size): x ** 2
# out: 10 loops, best of 3: 136 ms per loop

%timeit for x in xrange(size): x ** 2
# out: 10 loops, best of 3: 88.9 ms per loop

# avoid this
%timeit for x in np.arange(size): x ** 2
#out: 1 loops, best of 3: 1.16 s per loop

# use this
%timeit np.arange(size) ** 2
#out: 100 loops, best of 3: 19.5 ms per loop

Итак, для этого случая numpy в 4 раза быстрее, чем при использовании xrange, если вы это сделаете правильно. В зависимости от вашей проблемы numpy может быть намного быстрее, чем в 4 или 5 раз быстрее.

Ответ на этот вопрос объясняет еще несколько преимуществ использования массивов numpy вместо списков python для больших наборов данных.

Ответ 2

Прежде всего, как написано @bmu, вы должны использовать комбинации векторизованных вычислений, ufuncs и индексации. Есть действительно некоторые случаи, когда требуется явный цикл, но они действительно редки.

Если явный цикл необходим, с python 2.6 и 2.7, вы должны использовать xrange (см. ниже). Из того, что вы говорите, в Python 3 диапазон совпадает с xrange (возвращает генератор). Поэтому, возможно, диапазон подходит для вас.

Теперь вы должны попробовать сами (используя timeit: - здесь "волшебная функция" ipython):

%timeit for i in range(1000000): pass
[out] 10 loops, best of 3: 63.6 ms per loop

%timeit for i in np.arange(1000000): pass
[out] 10 loops, best of 3: 158 ms per loop

%timeit for i in xrange(1000000): pass
[out] 10 loops, best of 3: 23.4 ms per loop

Опять же, как упоминалось выше, большую часть времени можно использовать формулу numpy vector/array (или ufunc и т.д.), которые запускают скорость c: намного быстрее. Это то, что мы могли бы назвать "векторным программированием". Это упрощает реализацию программы, чем C (и более читаемо), но почти так же быстро в конце.