如何在numpy

时间:2018-01-19 14:21:34

标签: loops numpy exponential exponent

说我有以下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

1 个答案:

答案 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。那仍然有很好的想法。