【问题标题】:how to optimize iteration on exponential in numpy如何在numpy中优化指数迭代
【发布时间】:2018-01-19 14:21:34
【问题描述】:

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

我不介意将结果存储在二维数组而不是列表中的数组中。那可能会更干净。顺便说一句,我也尝试了以下方法,但它产生了类似的性能结果:

    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

【问题讨论】:

    标签: loops numpy exponential exponent


    【解决方案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。这仍然有很好的想法。

    【讨论】:

    • 谢谢,我使用了 np.vander 和您的答案的组合来创建我需要的东西。事实上,我有点需要计算 Vadermonde 矩阵,但使用你的答案,我可以做得更快。最后我所做的只是将一维数组添加到第一列:v1 = np.insert(v1, 0, np.ones(len(a)), axis=1)
    猜你喜欢
    • 2017-08-16
    • 1970-01-01
    • 2017-06-28
    • 1970-01-01
    • 1970-01-01
    • 2015-09-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多