我需要计算窗口大小为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
答案 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。