矢量数学 - numpy vs迭代器

时间:2014-02-21 21:44:07

标签: python numpy

下面的代码显示迭代器比numpy.arrays快很多(除非我做错了)。

import numpy as np
import itertools
import time

dim = 10000
arrays = [np.array((1, 2, 3)) for x in range(dim)]
iterators = [iter((1, 2, 3)) for x in range(dim)]

t_array = time.time()
print(sum(arrays))
print(time.time() - t_array)

# [10000 20000 30000]
# 0.016389131546020508


t_iterators = time.time()
print(list(sum(x) for x in zip(*iterators)))
print(time.time() - t_iterators)

# [10000, 20000, 30000]
# 0.0011029243469238281

迭代器版本不仅可以使用迭代器,还可以使用np.arrays,list或tuples。

所以,这是一个客观问题的地方,我猜这是一个客观原因numpy经常用于这种事情(基于我在互联网上看到的)。

这是什么原因?或者我做了客观错误的事情?

2 个答案:

答案 0 :(得分:3)

问题在于:

arrays = [np.array((1, 2, 3)) for x in range(dim)]

不是数组,而且:

sum(arrays)

不是一个笨拙的行动。

将时序与数组列表和内置sum

进行比较
>>> timeit.timeit('sum(arrays)', 'from __main__ import arrays', number=1000)
16.348400657162813

你得到的2D阵列和numpy.sum

>>> actual_array = numpy.array(arrays)
>>> timeit.timeit('numpy.sum(actual_array, axis=0)', 'from __main__ import actua
l_array; import numpy', number=1000)
0.20679712685881668
提高80倍。它比迭代器版本高出5倍。如果你打算使用NumPy,你需要尽可能多地保留NumPy中的工作。

答案 1 :(得分:2)

我会说你做错了,但这是一个解释问题,取决于你正在解决的问题的细节。

对于所呈现的情况,您将二维numpy数组存储为numpy数组列表,然后使用“list processing”例程。这避免了numpy中可能带来的一些好处/优化。

下面给出了在ipython(不运行%pylab)中运行的案例的略微修改版本。请注意,示例中您没有使用itertools,而是内置iter()函数。

import numpy as np

dim = 10000
arrays = [np.array((1, 2, 3)) for x in range(dim)]
iterators = [iter((1, 2, 3)) for x in range(dim)]

%timeit sum(arrays)
10 loops, best of 3: 20.8 ms per loop

%timeit list(sum(x) for x in zip(*iterators))
1000 loops, best of 3: 468 µs per loop

[根据以下评论编辑。]

所以迭代器看起来很棒但是它们有一个限制,因为它们只能使用一次;在我们迭代它们之后它们现在是“空的”。所以使用%timeit的正确测试是每次都重新创建迭代器。

def iter_test () :
    iterators = [iter((1, 2, 3)) for x in range(dim)]
    return list(sum(x) for x in zip(*iterators))

%timeit iter_test()
100 loops, best of 3: 4.06 ms per loop

现在我们看到它(仅)比循环数组快5倍。

在纯粹的numpy中,我会做以下(可以通过多种方式创建二维数组)

nparrays=np.asarray(arrays)
%timeit np.sum(nparrays,axis=0)
1000 loops, best of 3: 279 µs per loop

所以 的速度要快得多。