我刚刚开始知道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)
之间发表语句。
答案 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