说我有以下numpy array
n = 50
a = np.array(range(1, 1000)) / 1000.
我想执行这行代码
%timeit v = [a ** k for k in range(0, n)]
1000 loops, best of 3: 2.01 ms per loop
但是,这行代码最终将在循环中执行,因此我遇到了性能问题。
有没有办法优化循环?例如,列表推导中特定计算i
的结果只是循环中先前计算结果的结果,再次乘以a
。
我不介意将结果存储在2d数组中而不是列表中的数组中。那可能会更清洁。顺便说一句,我也尝试了以下内容,但它产生了类似的性能结果:
k = np.array(range(0, n))
ones = np.ones(n)
temp = np.outer(a, ones)
然后执行以下计算
%timeit temp ** k
1000 loops, best of 3: 1.96 ms per loop
或
%timeit np.power(temp, k)
1000 loops, best of 3: 1.92 ms per loop
但两者都产生与上面列表理解类似的结果。顺便说一下,n
在我的情况下总是integer
。
答案 0 :(得分:1)
在快速测试cumprod
似乎更快。
In [225]: timeit v = np.array([a ** k for k in range(0, n)])
2.76 ms ± 1.62 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
In [228]: %%timeit
...: A=np.broadcast_to(a[:,None],(len(a),50))
...: v1=np.cumprod(A,axis=1)
...:
208 µs ± 42.3 ns per loop (mean ± std. dev. of 7 runs, 1000 loops each)
为了比较我必须调整范围的值,因为v
包含0幂,而v1
以1幂开始:
In [224]: np.allclose(np.array(v)[1:], v1.T[:-1])
Out[224]: True
但时间表明cumprod
值得提炼。
建议的副本是Efficient way to compute the Vandermonde matrix。那仍然有很好的想法。