这是一个有趣的问题,因为我认为平均值的最优解与其他样本统计量的最优解不同。
我在下面提供了一个模拟示例,您可以进行操作。
首先,选择一些任意参数,模拟一些数据:
%#Set some arbitrary parameters
T = 100; N = 5;
WindowLength = 10;
%#Simulate some data
X = randn(T, N);
对于均值,使用filter 获得移动平均线:
MeanMA = filter(ones(1, WindowLength) / WindowLength, 1, X);
MeanMA(1:WindowLength-1, :) = nan;
我原本想用conv来解决这个问题,如下:
MeanMA = nan(T, N);
for n = 1:N
MeanMA(WindowLength:T, n) = conv(X(:, n), ones(WindowLength, 1), 'valid');
end
MeanMA = (1/WindowLength) * MeanMA;
但正如@PhilGoddard 在 cmets 中指出的那样,filter 方法避免了循环的需要。
还请注意,我已选择使输出矩阵中的日期与X 中的日期相对应,因此在以后的工作中,您可以对两者使用相同的下标。因此,MeanMA 中的第一个 WindowLength-1 观测值将是 nan。
对于方差,我看不出如何使用filter 或conv 甚至是运行总和来提高效率,因此我在每次迭代时手动执行计算:
VarianceMA = nan(T, N);
for t = WindowLength:T
VarianceMA(t, :) = var(X(t-WindowLength+1:t, :));
end
我们可以利用我们已经计算平均移动平均线的事实稍微加快速度。只需将上面的循环内行替换为:
VarianceMA(t, :) = (1/(WindowLength-1)) * sum((bsxfun(@minus, X(t-WindowLength+1:t, :), MeanMA(t, :))).^2);
但是,我怀疑这会有很大的不同。
如果其他人能看到使用filter 或conv 获得移动窗口方差的巧妙方法,我将非常有兴趣看到它。
我将偏度和峰度的情况留给 OP,因为它们本质上与方差示例相同,但具有适当的功能。
最后一点:如果您要将上述转换为通用函数,则可以传入一个匿名函数作为参数之一,然后您将拥有一个移动平均例程,可用于任意选择转换。
最后,最后一点:对于一系列窗口长度,只需为每个窗口长度循环整个代码块。