【问题标题】:Simple vectorization of taking the product and then sum of a list-like object取乘积然后求和类似列表的对象的简单向量化
【发布时间】:2017-06-18 10:31:20
【问题描述】:

我想做一个看似简单的操作,也许我只是被阻止了,但是执行这个计算的最快方法是什么?

mret = 0
for i in range(1, len(monthly_rets)):
    mret += monthly_rets[i:].prod()

monthly_rets 是一个长度为 2-540 的 np.array(即它的长度可以在 2 到 540 之间变化,它不一定是 np.array)的每月因子回报(对于题)。一定有一些聪明的技巧可以用来避免使用 for 循环并加快速度吗?

【问题讨论】:

    标签: python pandas numpy vectorization


    【解决方案1】:

    您可以使用np.cumprodnp.sum 的组合。像这样的东西应该可以工作(至少对于 numpy 数组):

    mret = monthly_rets[:0:-1].cumprod().sum()
    

    np.cumprod 计算数组的累积乘积,这意味着如果您有一个包含三个元素 a[0]a[1]a[2] 的数组 aa.cumprod() 将为您提供数组 [a[0], a[0]*a[1], a[0]*a[1]*a[2]]。现在你想要类似的东西。这是通过使用切片[:0:-1] 来完成的,该切片将向后遍历数组,并以倒数第二个元素结束,这样a[:0:-1].cumprod() 将为您提供[a[2], a[1]*a[2]]sum() 然后将总结所有元素以提供您的结果。 (感谢@B.M. 指出正确的切片。)

    顺便说一句,我使用 ipython%timeit 检查了 540 个随机数数组(对应于您的最大数组)的性能优势。我得到了 2.3ms/10µs=230 的加速。即使算上%timeit 警告的缓存效果(可能是错误的),你肯定有至少 40 的加速。

    【讨论】:

    • monthly_rets[:0:-1] 得到相同的结果。
    • 感谢您的详细解释,我对您的公式进行了轻微修改,这给了我想要的答案(额外的 [:-1]):mret2 =monthly_rets[::-1] [:-1].cumprod().sum()
    • 是的,我刚刚看到,您想排除 [0] 元素。我更新了我的解决方案。
    猜你喜欢
    • 1970-01-01
    • 2021-08-05
    • 2017-04-07
    • 1970-01-01
    • 2022-01-19
    • 1970-01-01
    • 2018-05-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多