众所周知,如果a
是一个numpy数组,那么a.tolist()
比list(a)
更快,例如:
>>> import numpy as np
>>> big_np=np.random.randint(1,10**7,(10**7,))
>>> %timeit list(big_np)
1 loop, best of 3: 869 ms per loop
>>> %timeit big_np.tolist()
1 loop, best of 3: 306 ms per loop
那意味着,天真的
list(a)
版本比特殊函数tolist()
慢大约3
倍。然而,与内置的array
模块的性能相比:>>> import array
>>> big_arr=array.array('i', big_np)
>>> %timeit list(big_arr)
1 loop, best of 3: 312 ms per loop
我们可以看到,应该说
list(a)
很慢而不是tolist()
很快,因为array.array
和特殊函数一样快。另一个观察结果是:
array.array
模块和tolist
从small-integer-pool(即值在[-5, 256]
范围内)中受益,但对于list(a)
则不是这种情况。##only small integers:
>>> small_np=np.random.randint(1,250, (10**7,))
>>> small_arr=array.array('i', small_np)
>>> %timeit list(small_np)
1 loop, best of 3: 873 ms per loop
>>> %timeit small_np.tolist()
10 loops, best of 3: 188 ms per loop
>>> %timeit list(small_arr)
10 loops, best of 3: 150 ms per loop
正如我们所看到的,更快的版本大约快了两倍,但慢速版本与以前一样慢。
我的问题是:相对于
list(array.array)
,什么使list(numpy.array)
变慢?编辑:
另一个观察结果是,在Python2.7中,如果整数更大(即不能由
int32
保存),则需要更长时间:>>> very_big=np.random.randint(1,10**7,(10**7,))+10**17
>>> not_so_big=np.random.randint(1,10**7,(10**7,))+10**9
>>> %timeit very_big.tolist()
1 loop, best of 3: 627 ms per loop
>>> %timeit not_so_big.tolist()
1 loop, best of 3: 302 ms per loop
但仍然比缓慢的列表版本快。
array.array
使用迭代器,速度仍然很快吗? - eadlist(numpy-array)
,它是<type 'numpy.int32'>
,否则为int
。 - eadlist
迭代第一维。如果数组是二维的,则结果是一个由一维数组组成的列表。通常情况下,list
和tolist
不会产生相同的结果,并且不应该期望它们在速度上可比较。 - hpaulj