【问题标题】:Find the average value between each element of the array and its immediate neighbor求数组的每个元素与其直接相邻元素之间的平均值
【发布时间】:2014-04-13 19:38:06
【问题描述】:

假设我有一个 1 x n 的矩阵 1a1,我想找到 a 的每个元素与其相邻元素之间的平均值。

这样做的聪明方法是什么?

前:

如果

a=[0 1 2 1 0 1];

那么“平均值矩阵”就是:

b=[0.5 1 1.33 1 0.5];

b 的第一个条目是:

b(1) = (0+1)/2 = 0.5
b(2) = (0+1+2)/3 = 1

等等

【问题讨论】:

    标签: matlab matrix average


    【解决方案1】:

    我建议将中间作为向量运算并将边缘条件作为标量处理。

        b=zeros(size(a));
        b(2:end-1)=(a(1:end-2)+a(2:end-1)+a(3:end))/3;
        b(1)=(a(1)+a(2))/2;
        b(end)=(a(end-1)+a(end))/2;
    

    如果你得到更大的平均值......

        % scale and sum elements with a sliding window 3 long.
        b=conv(a,[1,1,1]/3)
        %
        % remove the tails
        b=b(2:end-1)
        % 
        % and rescale the edge cases.
        b(1)=b(1)*3/2
        b(end)=b(end)*3/2
    

    我比较了上面第一种方法(向量),卷积方法和RDizzl3建议的hankel方法。 (对不起,Luis,我没有 Statistics 包,虽然我预计 nanmean 方法会由于条件检查的数量而变慢。)比较是使用 10000 长度的随机向量,以使时间显着。在这些计时完成之前,b 被初始化为正确大小的零矩阵。正确大小的汉克尔矩阵(h)也在这些计时之前被预先计算。

        % hankle method
        tic; b(1)=mean(a([1,2])); b(2:(n-1))=mean(a(h),2); b(2)=mean(a([n-1,n])); toc
        Elapsed time is 0.001698 seconds.
        % convolution method
        tic; c=conv(a,[1,1,1]/3) ; b=c(2:(2+n-1)); b(1)=b(1)*3/2; b(n)=b(n)*3/2; toc;
        Elapsed time is 0.000339 seconds.
        % vector method
        tic; b(1)=mean(a([1,2])) ; b(2:(n-1))=(a(1:(n-2))+a(2:(n-1))+a(3:n))/3;b(2)=mean(a([n-1,n])); toc
        Elapsed time is 0.000914 seconds.
    

    上面我又重复了3次,对结果进行了排序,

        hankel       convolution  vector
        9.2500e-04   3.3900e-04   7.2600e-04
        1.3820e-03   5.2600e-04   8.7100e-04
        1.6980e-03   5.5200e-04   9.1400e-04
        2.1570e-03   5.5300e-04   2.6390e-03
    

    我有点惊讶,我没想到卷积方法的效率直到更大的窗口尺寸才会出现。但它一直在这里做得最好。

    请注意,如果您使用较小的数据集,这些时间可能不合适。如果感兴趣的是大量较短长度的向量,如果 hankel 方法效果更好,我一点也不感到惊讶。

    【讨论】:

      【解决方案2】:

      你可以用这个:

      a=[0 1 2 1 0 1];
      n = numel(a);
      h = hankel(1:(n-2),(n-2):n);
      b(1) = mean(a([1 2]))
      b(2:(n-1)) = mean(a(h),2);
      b(n) = mean(a([n-1 n]))
      

      这将返回向量:

      b =  [0.5000    1.0000    1.3333    1.0000    0.6667    0.5000]
      

      这会从向量 a 中获取元素并为其邻居求平均值,因此:

      b(1) = (0+1)/2 = 0.5
      b(2) = (0+1+2)/3 = 1
      b(3) = (1+2+1)/3 = 1.3333
      b(4) = (2+1+0)/3 = 1
      b(5) = (1+0+1)/3 = 0.6667
      b(6) = (0+1)/2 = 0.5 % last element 
      

      【讨论】:

        【解决方案3】:
        a = [0 1 2 1 0 1]; %// data
        n = 1; %// how many neighbours to consider on each side
        
        a2 = [NaN(1,n) a NaN(1,n)]; %// pad with NaN's (which will be ignored by nanmean)
        b = arrayfun(@(k) nanmean(a2(k-n:k+n)), n+1:n+numel(a)); %// apply a
        %// sliding-window mean ignoring NaN's
        

        【讨论】:

          【解决方案4】:

          使用平滑过滤器的最简单方法

          output=smooth(A,3,'moving');
          

          其中 3 是窗口大小(应该是奇数值)

          检查文档以获得平滑功能

          https://www.mathworks.com/help/curvefit/smooth.html

          【讨论】:

            猜你喜欢
            • 2016-11-09
            • 2019-11-27
            • 1970-01-01
            • 1970-01-01
            • 2013-12-29
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多