Я просто узнаю numpy, и я впечатлен его требованиями подобной C эффективности с доступом к памяти в его ndarrays. Я хотел видеть различия между ними и списками pythonic для меня, таким образом, я запустил быстрый тест синхронизации, выполнив несколько из тех же простых задач с numpy без него. Numpy превзошел обычные списки порядком величины в выделении и арифметических операциях на массивах, как ожидалось. Но этот сегмент кода, идентичного в обоих тестах, взял о 1/8 секунды с обычным списком, и немного более чем 2,5 секунды с numpy:
file = open('timing.log','w')
for num in a2:
if num % 1000 == 0:
file.write("Multiple of 1000!\r\n")
file.close()
Кто-либо знает, почему это могло бы быть, и если существует некоторый другой синтаксис, который я должен использовать для операций как это, чтобы воспользоваться лучшим преимуществом того, что может сделать ndarray?
Спасибо...
Править: Ответить на комментарий Wayne... Я неоднократно синхронизировал их обоих и в различных заказах и получал в значительной степени идентичные результаты каждый раз, таким образом, я сомневаюсь, что это - другой процесс. Я поместил
start = time()
наверху файла после импорта numpy и затем у меня есть операторы как print 'Time after traversal:\t',(time() - start)
повсюду. a2
- это массив NumPy, верно? Одна из возможных причин, по которой это может длиться так долго в NumPy (если деятельность других процессов не учитывает это, как предложил Уэйн Вернер), заключается в том, что вы выполняете итерацию по массиву с помощью цикла Python. На каждом шаге итерации Python должен извлечь одно значение из массива NumPy и преобразовать его в целое число Python, что не является особенно быстрой операцией.
NumPy работает намного лучше, когда вы можете выполнять операции со всем массивом как единым целым. В вашем случае одним из вариантов (возможно, даже не самым быстрым) будет
file.write("Multiple of 1000!\r\n" * (a2 % 1000 == 0).sum())
Попробуйте сравнить его с эквивалентом на чистом Python,
file.write("Multiple of 1000!\r\n" * sum(filter(lambda i: i % 1000 == 0, a2)))
или
file.write("Multiple of 1000!\r\n" * sum(1 for i in a2 if i % 1000 == 0))
Я не удивлен, что NumPy плохо справляется со встроенными модулями Python при использовании вашего фрагмента. Большая часть повышения производительности в NumPy возникает из-за избегания циклов и вместо доступа к массиву путем индексации:
В NumPy чаще всего используется что-то вроде этого:
A = NP.random.randint(10, 100, 100).reshape(10, 10)
w = A[A % 2 == 0]
NP.save("test_file.npy", w)
Доступ к отдельным элементам очень медленный для массивов numpy. Используйте векторные операции:
$ python -mtimeit -s 'import numpy as np; a2=np.arange(10**6)' '
> sum(1 for i in a2 if i % 1000 == 0)'
10 loops, best of 3: 1.53 sec per loop
$ python -mtimeit -s 'import numpy as np; a2=np.arange(10**6)' '
> (a2 % 1000 == 0).sum()'
10 loops, best of 3: 22.6 msec per loop
$ python -mtimeit -s 'import numpy as np; a2= range(10**6)' '
> sum(1 for i in a2 if i % 1000 == 0)'
10 loops, best of 3: 90.9 msec per loop