2013-08-05 2 views
2

Нумик должен быть быстрым. Однако при сравнении Numpy ufuncs со стандартными функциями Python я обнаружил, что последние намного быстрее.Являются ли функции Numpy медленными?

Например,

aa = np.arange(1000000, dtype = float) 
%timeit np.mean(aa) # 1000 loops, best of 3: 1.15 ms per loop 
%timeit aa.mean # 10000000 loops, best of 3: 69.5 ns per loop 

Я получил аналогичные результаты с другими функциями Numpy как макс, мощности. У меня создалось впечатление, что у Numpy есть накладные расходы, что делает его медленнее для небольших массивов, но будет быстрее для больших массивов. В коде выше aa не мало: он имеет 1 миллион элементов. Я что-то упускаю?

Конечно, Numpy быстро, только функции, как представляется, медленно:

bb = range(1000000) 
%timeit mean(bb) # 1 loops, best of 3: 551 ms per loop 
%timeit mean(list(bb)) # 10 loops, best of 3: 136 ms per loop 
+0

Какую версию Python вы используете? В Python 2 'range()' возвращает список.В Python 3 'range()' возвращает итератор. Это окажет огромное влияние на ваши измерения производительности. –

+0

'np.mean (aa)' и 'aa.mean' кажутся одинаковой функцией. –

+8

FYI, 'aa.mean' ничего не делает. Вы не называете эту функцию, вы ее называете. Вот почему это так быстро. IOW, вам нужно 'aa.mean()'. – DSM

ответ

4

Вы не вызывая aa.mean. Поместите скобки для вызова функций в конец, чтобы на самом деле вызвать его, а разность скоростей почти исчезнет. (Оба np.mean(aa) и aa.mean() не NumPy, и не использует встроенные команды Python, чтобы сделать математику.)

4

Другие уже отмечали, что ваше сравнение не реальное сравнение (вы не вызов функции + оба NumPy).
Но для ответа на вопрос «Медленно ли функция numpy?»: вообще говоря, нет, функция numpy не медленна (или не медленнее, чем простая функция python). Конечно, есть некоторые побочные примечания:

  • «Slow» зависит от курса на то, с чем вы сравниваете, и он всегда может быть быстрее. С такими вещами, как cython, numexpr, numba, вызывающий C-код, ... и другие, во многих случаях, безусловно, можно получить более быстрые результаты.
  • У Numpy есть определенные накладные расходы, которые могут быть значительными в некоторых случаях. Например, как вы уже упоминали, numpy может быть медленнее на небольших массивах и скалярной математике. Для сравнения по этому вопросу см например Are NumPy's math functions faster than Python's?

Для сравнения вы хотели сделать:

In [1]: import numpy as np 
In [2]: aa = np.arange(1000000) 
In [3]: bb = range(1000000) 

для mean (обратите внимания, что нет средней функции питона стандартной библиотеки: Calculating arithmetic mean (average) in Python):

In [4]: %timeit np.mean(aa) 
100 loops, best of 3: 2.07 ms per loop 

In [5]: %timeit float(sum(bb))/len(bb) 
10 loops, best of 3: 69.5 ms per loop 

Для max, NumPy против простого питона:

In [6]: %timeit np.max(aa) 
1000 loops, best of 3: 1.52 ms per loop 

In [7]: %timeit max(bb) 
10 loops, best of 3: 31.2 ms per loop 

В заключительной ноте, в приведенном выше сравнении я использовал Numpy массив (aa) для функций Numpy и списка (bb) для простых функций питона. Если вы будете использовать список с Numpy функций, в этом случае он снова будет медленнее:

In [10]: %timeit np.max(bb) 
10 loops, best of 3: 115 ms per loop 

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