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.
source to share
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 vectory
using a move middle filter. The results are returned in a column vectoryy
. 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');
source to share
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.
source to share
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.
source to share