移动(滑动)窗口平均值以在Matlab中创建基线

时间:2017-04-25 15:55:59

标签: matlab

我需要计算窗口大小为20个样本的移动窗口平均值。该窗口应该在整个数据中移动。示例:对于前20个样本,它将计算平均值,窗口从0移动到20和21,并计算1到21个样本的平均值,并且应该继续进行。

我编写了一个代码,其中'x'变量加载了.dat文件,并且已经编写了for循环来计算均值。代码如下

clear all;
close all;
x= load ('cpp1500.dat');
for i=1:length(x)
    s(i)=sum(x(1:i));
  r(i)=s(i)./i;
end

plot(x,'R')
hold on;
plot(r)

请建议我一种计算移动窗口平均值的方法。 Graphs of samples v/s sensor data

3 个答案:

答案 0 :(得分:0)

这很容易做到。您只需使用for循环的索引来帮助您为您计算。您可以从i转到i,而不是从1到i + 19。您需要确保for循环不会超出信号范围,因此您需要迭代到length(x) - 19。在进入下一个窗口之前,您还需要将信号除以20:

clear all;
close all;
x = load ('cpp1500.dat');
for i = 1 : length(x) - 19 % Change
    s(i) = sum(x(i : i + 19)); % Change
    r(i) = s(i) / 20; % Change
end

plot(x,'R');
hold on;
plot(r)

但是,如果我可以推荐一些东西,请不要在这里使用循环。使用filter并将右侧系数指定为全1,而左侧系数为20.您还必须认识到会有延迟,因为它会在您收集20个样本之前立即过滤信号移动平均线。因此,您需要在完成后从输出中删除前19个样本:

clear all;
close all;
x = load ('cpp1500.dat');
r = filter(ones(20, 1), 20, x(:));
r = r(20 : end);
plot(x, 'R');
hold on;
plot(r);

请注意,我不知道你加载的矢量是什么结构,所以我确保它是一个列矢量。

答案 1 :(得分:0)

在您的代码中,您似乎混淆了一些索引。要回答这个问题(这不是推荐的版本,请参阅下面的版本)

clear all;
close all;
x= load ('cpp1500.dat');
wndSize = 20;
for i=1:length(x) - wndSize
  s(i)=sum(x(i:i + wndSize));
end
r = s ./ wndSize

plot(x,'R')
坚持; 积(r)的

Matlab通常会对运行时较长的数组进行循环处理。您希望使用大小为20的盒式过滤器执行1d过滤,其中Matlab恰好具有高效实现的功能。这应该可以解决问题:

windowSize = 20; 
b = (1/windowSize)*ones(1,windowSize);
a = 1;

r = filter( b, a, x )

请注意,过滤器的实现与x中元素的处理略有不同,这些元素接近于windowSize到数组的末尾。但是,它产生了可用的滑动平均值。

另请参阅:https://de.mathworks.com/help/matlab/ref/filter.html?requestedDomain=www.mathworks.com

答案 2 :(得分:0)

如果你是R2016a或更高版本,你可以使用movmean function来执行此操作。

r = movmean(x, [0 19]);

将从当前点开始采用20点移动平均线,并在左侧使用19点。该功能还有其他选项,具体取决于您希望如何对齐窗口,处理端点,tec。