You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过循环逐步扩展numpy数组元素计算滚动方差?

高效计算滚动前i项方差的方法

嘿,这个问题问得很实在!你一开始想到的循环截取前i个元素计算方差的思路,虽然能实现需求,但存在一个明显的问题——重复计算太多。比如计算前3个元素的方差时,其实已经包含了前2个元素的计算结果,但切片重新计算相当于把前面的工作又做了一遍,当数组规模很大时,时间复杂度会达到O(n²),效率会很低。

更优的思路:增量式计算

方差的本质可以通过两个统计量推导出来:

总体方差公式:$\text{Var}(X) = E[X^2] - (E[X])^2$
其中$E[X]$是均值,$E[X^2]$是元素平方的均值

基于这个公式,我们只需要维护三个累计变量,就能在遍历数组时每一步只用当前新增的元素更新统计量,不需要重复计算前面的所有元素:

  • n:当前累计的元素个数
  • sum_x:当前累计的元素总和
  • sum_x2:当前累计的元素平方和

每新增一个元素x,我们只需要做这几步更新:

  1. n += 1
  2. sum_x += x
  3. sum_x2 += x ** 2

然后用更新后的变量计算当前的均值、平方均值,最后代入方差公式即可。如果需要样本方差(统计中常用,除以n-1),只需要在总体方差的基础上做一点调整。

Python代码实现

def rolling_variance(arr, sample=False):
    n = 0
    sum_x = 0.0
    sum_x2 = 0.0
    rolling_vars = []
    for x in arr:
        n += 1
        sum_x += x
        sum_x2 += x ** 2
        mean = sum_x / n
        mean_x2 = sum_x2 / n
        # 计算总体方差
        var = mean_x2 - mean ** 2
        # 如果是样本方差,调整计算方式(n=1时样本方差无意义,设为0)
        if sample and n > 1:
            var = var * n / (n - 1)
        rolling_vars.append(var)
    return rolling_vars

# 测试示例
test_arr = [1, 6, 12, 4]
print("总体滚动方差:", rolling_variance(test_arr))
print("样本滚动方差:", rolling_variance(test_arr, sample=True))

运行结果:

总体滚动方差: [0.0, 6.25, 18.88888888888889, 15.1875]
样本滚动方差: [0.0, 12.5, 28.333333333333332, 20.25]

用Numpy实现向量化计算(适合大型数组)

如果你习惯用Numpy处理数值计算,可以用cumsum函数直接计算累计和与累计平方和,实现向量化的增量计算,效率会更高:

import numpy as np

def numpy_rolling_variance(arr, sample=False):
    arr_np = np.array(arr, dtype=np.float64)
    n = np.arange(1, len(arr_np)+1)
    sum_x = np.cumsum(arr_np)
    sum_x2 = np.cumsum(arr_np ** 2)
    
    mean = sum_x / n
    mean_x2 = sum_x2 / n
    var = mean_x2 - mean ** 2
    
    if sample:
        # 处理n=1的情况,避免除以0
        var[1:] = var[1:] * n[1:] / (n[1:] - 1)
    return var

# 测试
test_arr = [1, 6, 12, 4]
print("Numpy总体滚动方差:", numpy_rolling_variance(test_arr))
print("Numpy样本滚动方差:", numpy_rolling_variance(test_arr, sample=True))

为什么这个方法更好?

  • 时间复杂度是O(n):每个元素只被处理一次,没有重复计算,数组越大,和切片法的效率差距越明显。
  • 内存效率高:只需要维护几个变量(或Numpy的几个一维数组),不需要每次生成新的切片数组。

内容的提问来源于stack exchange,提问作者Ant

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 07:48:54