Moving average calculation

I need to calculate a moving average over a series of data in a for loop. I should get a moving average of N = 9 days. The array I'm calculating is 4 series of 365 values ​​(M), which are themselves the average of another dataset. I want to plot the averages of my moving average data in one chart.

I searched a bit for information on moving averages and the "conv" command and found what I was trying to implement in my code.

hold on
for ii=1:4;
    M=mean(C{ii},2)
    wts = [1/24;repmat(1/12,11,1);1/24];
    Ms=conv(M,wts,'valid')
    plot(M)
    plot(Ms,'r')

end
hold off

      

So, basically, I am calculating my average and plotting it with the (wrong) moving average. I selected "wts" directly from the mathworks site, so this is not correct. (source: http://www.mathworks.nl/help/econ/moving-average-trend-estimation.html ) My problem is that I don't understand what this "wts" is. Can anyone please explain? If it has something to do with the weights of the values: this is not valid in this case. All values ​​are weighted equally.

And if I am doing it completely wrong, can I get some help?

I sincerely thank you.

+3


source to share


4 answers


There are two more alternatives:

1) filter

From the doc:

You can use filter

to find the average without using a for loop. This example finds the average of a 16-element vector using a window size of 5.

data = [1:0.2:4]'; %'
windowSize = 5;
filter(ones(1,windowSize)/windowSize,1,data)

      



2) as part of the curve set toolkit (which is available in most cases) smooth

From the doc:

yy = smooth(y)

smooths the data in the column vector y

using a move middle filter. The results are returned in a column vector yy

. The default range for the moving average is 5.

%// Create noisy data with outliers:

x = 15*rand(150,1); 
y = sin(x) + 0.5*(rand(size(x))-0.5);
y(ceil(length(x)*rand(2,1))) = 3;

%//  Smooth the data using the loess and rloess methods with a span of 10%:

yy1 = smooth(x,y,0.1,'loess');
yy2 = smooth(x,y,0.1,'rloess');

      

+4


source


In 2016 MATLAB added a function movmean

that calculates the moving average:



N = 9;
M_moving_average = movmean(M,N)

      

+4


source


Using conv is a great way to implement a moving average. In the code you are using, wts is how much you weigh each value (you guessed it). the sum of this vector must always be equal to one. If you want to distribute each value evenly and make a moving filter of size N, then you would like to do

N = 7;
wts = ones(N,1)/N;
sum(wts) % result = 1

      

Using the "valid" argument to conv will result in fewer values ​​in Ms than in M. Use "same" if you don't mind the effects of zero padding. If you have a signal processing panel, you can use cconv if you want to try a circular moving average. Something like

N = 7;
wts = ones(N,1)/N;
cconv(x,wts,N);

      

must work.

You should read conv and cconv for more information if you haven't already.

+3


source


I would use this:

% does moving average on signal x, window size is w
function y = movingAverage(x, w)
   k = ones(1, w) / w
   y = conv(x, k, 'same');
end

      

ripped right out of here .

Comment on the current implementation. wts

- the weight vector, which is from Mathworks, is a 13-point average, with particular attention to the first and last point of the rest's weight fractions.

0


source







All Articles