首页 > 解决方案 > 如何添加标准偏差和移动平均线

问题描述

我想要的是:我有 32 个txt文件和 1个excle文件的文件夹,每个文件包含两列中的一些数据:时间、级别。

我已经设法从文件夹中提取数据并打开每个文件Matlab并从中获取数据。我需要做的是为每个数据文件创建绘图。32 个地块中的每一个都应具有:

  1. 随时间变化的平均值
  2. 标准差

有了这两件事,我就无法让它发挥作用。这次我还需要制作另一个图,该图应该具有所有 32 个文件中每分钟的平均值。

到目前为止,这是我的代码:

clc,clear;
myDir = 'my path';
dirInfo = dir([myDir,'*.txt']);
filenames = {dirInfo.name};
N = numel(filenames);
data=cell(N,1); 
for i=1:N
    fid = fopen([myDir,filenames{i}] );
    data{i} = textscan(fid,'%f %f','headerlines',2);
    fclose(fid);
    temp1=data{i,1};
    time=temp1{1};
    level=temp1{2};
    Average(i)=mean(level(1:find(time>60)));
    AverageVec=ones(length(time),1).*Average(i);
    Standard=std(level);
    figure(i);
    plot(time,level);
    xlim([0 60]);
    hold on
    plot(time, AverageVec);
    hold on
    plot(time, Standard);
    legend('Level','Average','Standard Deviation')
end 

这段代码的主要问题是我只得到了整个 60 秒的平均值,而不是移动平均值,标准偏差什么也没返回。

你需要知道的几件事:

标签: matlab

解决方案


显然,您需要 movmean 和 movstd 的替代品,因为它们是在 2016a 中引入的。我将@bla 的建议与纠正边缘效应的两个循环结合起来。

function [movmean,movstd] = moving_ms(vec,k)
if mod(k,2)==0,k=k+1;end
L = length(vec);
movmean=conv(vec,ones(k,1)./k,'same');
% correct edges
n=(k-1)/2;
movmean(1) = mean(vec(1:n+1));
N=n;
for ct = 2:n
    movmean(ct) = movmean(ct-1) + (vec(ct+n) - movmean(ct-1))/N;
    N=N+1;
end
movmean(L) = mean(vec((L-n):L));
N=n;
for ct = (L-1):-1:(L-n)
    movmean(ct) = movmean(ct+1) + (vec(ct-n) - movmean(ct+1))/N;
    N=N+1;
end

%mov variance
movstd = nan(size(vec));
for ct = 1:n
    movstd(ct) = sum((vec(1:n+ct)-movmean(ct)).^2);
    movstd(ct) = movstd(ct)/(n+ct-1);
end
for ct = n+1:(L-n)
    movstd(ct) = sum((vec((ct-n):(ct+n))-movmean(ct)).^2);
    movstd(ct) = movstd(ct)/(k-1);
end
for ct = (L-n):L
    movstd(ct) = sum((vec((ct-n):L)-movmean(ct)).^2);
    movstd(ct) = movstd(ct)/(L-ct+n);
end
movstd=sqrt(movstd);

matlab >=2016a 的人可以使用以下方法进行比较:

v=rand(1,1E3);m1 = movmean(v,101);s1=movstd(v,101);
[m2,s2] = moving_ms(v,101);
x=1:1E3;figure(1);clf;
subplot(1,2,1);plot(x,m1,x,m2);
subplot(1,2,2);plot(x,s1,x,s2);

它应该显示一条红线,因为蓝线是重叠的。


推荐阅读