如何通过numpy数组最大化效率?

时间:2010-08-03 18:05:51

标签: python performance numpy

我刚刚开始知道numpy,我对它的ndarray中的内存访问类C效率的说法印象深刻。我想看看这些和pythonic列表之间的区别对于我自己,所以我进行了快速计时测试,在没有它的情况下执行一些相同的简单任务numpy。正如预期的那样,Numpy在数组的分配和算术运算中将常规列表的数量超出了一个数量级。但是这两段代码在两个测试中都相同,使用常规列表大约需要1/8秒,而numpy则需要2.5秒以上:

file = open('timing.log','w')
for num in a2:
    if num % 1000 == 0:
        file.write("Multiple of 1000!\r\n")

file.close()

有没有人知道为什么会这样,如果有其他语法我应该用于这样的操作,以更好地利用ndarray可以做的事情?

...谢谢

编辑:回答Wayne的评论......我反复按时间顺序对他们进行计时,每次都得到几乎相同的结果,所以我怀疑这是另一个过程。在numpy导入之后我将

start = time()
放在文件的顶部,然后我会在
print 'Time after traversal:\t',(time() - start)
之间发表语句。

3 个答案:

答案 0 :(得分:10)

a2是一个NumPy数组,对吧?可能在NumPy中花费这么长时间的一个可能原因(如果其他进程的活动没有像Wayne Werner所建议的那样解释它)是你使用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))

答案 1 :(得分:6)

在使用你的代码片段时,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)

答案 2 :(得分:5)

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