модуль timeit в python не распознает модуль numpy

Я хочу проверить время обработки между двумя идентичными списками, особенно для обычного списка и списка numpy. Мой код

import timeit
import numpy as np

t = timeit.Timer("range(1000)")
print t.timeit()

u = timeit.Timer("np.arange(1000)")
print u.timeit()

Расчет для t в порядке, но для u NameError: в списке указано глобальное имя «np» не определено.

Как я должен закодировать его, чтобы получить время обработки?


person user3211991    schedule 19.01.2014    source источник


Ответы (3)


Класс timeit.Timer можно использовать двумя разными способами.

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

Итак, у вас есть два варианта:

u = timeit.Timer("np.arange(1000)", setup='import numpy as np')

… or …

u = timeit.Timer(lambda: np.arange(1000))

В первом случае тот факт, что вы совершили import numpy as np, не имеет значения; он не влияет на среду, в которой компилируется и выполняется np.arange(1000) (поэтому вы должны включить его в бит setup=...).

Во втором случае тот факт, что вы выполнили import numpy as np, очевидно, имеет значение — он влияет на среду, в которой оценивается ваш код, включая lambda: np.arange(1000).

person abarnert    schedule 19.01.2014

Используйте параметр setup:

u = timeit.Timer("np.arange(1000)", setup='import numpy as np')
person ndpu    schedule 19.01.2014
comment
Спасибо за код. Теперь, когда я знаю время, знаете ли вы, почему время в обычном списке (10,4 с) намного больше, чем в массиве (1,9 с)? - person user3211991; 19.01.2014
comment
@user3211991 range(1000) создает список в памяти, попробуйте заменить range(1000) на xrange(1000), stackoverflow.com/questions/94935/ - person ndpu; 19.01.2014
comment
Также см. более эффективный"> stackoverflow.com/questions/10698858/ для более подробной информации об эффективности между диапазоном и np.arange - person Ffisegydd; 19.01.2014
comment
@user3211991: Это действительно отдельный вопрос… но в целом создание 1000 объектов Python int плюс список для их хранения займет больше времени, чем создание и инициализация массива из 1000 объектов C int. В этом половина смысла NumPy — отсутствие упаковки каждого значения в объекте Python экономит все время упаковки и распаковки. (Другая половина вопроса заключается в том, что он также экономит память для этих 1000 блоков. И третья половина — поскольку NumPy достаточно крут, чтобы иметь более чем 100% совершенства — заключается в том, что он предлагает хорошие API для операций с элементами.) - person abarnert; 19.01.2014

Чтобы использовать импортированные библиотеки с timeit, вы должны импортировать их с помощью аргумента ключевого слова setup (документы):

import timeit

# Doesn't require setup kwarg as range doesn't need to be imported.
t = timeit.Timer("range(1000)")
print t.timeit()

# Requires the import of numpy (as np) through the setup kwarg.
u = timeit.Timer("np.arange(1000)", setup = 'import numpy as np')
print(u.timeit())

Аргумент ключевого слова setup позволяет настроить код, например, импортировать внешние библиотеки или импортировать функции из кода с помощью from __main__ import func.

person Ffisegydd    schedule 19.01.2014
comment
Нет, вам не нужно импортировать их с помощью аргумента ключевого слова setup. Если вы передаете вызываемый объект вместо компилируемого кода, вызываемый объект уже был скомпилирован в вашей обычной среде (включая любые операторы import) и работает нормально. - person abarnert; 19.01.2014