How can I calculate a centered moving average with window size 7?

8 次查看(过去 30 天)
Hello,
I want to calculate centered moving average of daily values using a 7-day window. That is I want to start with the 4th day being the first center and continue until the 1318 as the last center. And I want the filter to proceed successively from day 4, then 5, then 6, and so on until day 1318 as the center. I have 1321 daily values. I have NaN values in blocks and scattered throughout the data but would like to keep them. I've been given the below code but because I do not know programming, I can not make sense of how I can adapt this to get what I want done. My variable is called Imn_EVI2_d. Thank you for any help.
Daywind=3.5; % window size (days/2, i.e. half of the weekly window width)
Inc=1; %Time step increment (days)
binwid = (Daywind)/1321; %Specifies bin size
start = min(1); %Specifies timestamp when dataset starts Change
last = max(1321); %Specifies timestamp when dataset ends Change
bincenter = start+binwid:(Inc/1321):(last+1); %Specifies center of bin
binnum=length(bincenter); %Specifies how many bins for window size*
Imn_EVI2_d=m;
Imn_EVI2_avgmovall=[]; %Array that moving average will go into. Right now it is empty and 0x0.
Imn_EVI2_d=Imn_EVI2_d(1,:)'; %Change
%This is a for loop that takes the bins above and averages them and takes
%the average and saves it to EVIavgmovall
for i = 1:1:(binnum);
focusday = (1 >= (bincenter(i)-binwid) & (1321 <= (bincenter(i) + binwid)));
EVI_period = Imn_EVI2_d(focusday);
figure(1)
plot(DYear(focusday),Imn_EVI2_d(focusday),'.')
Imn_EVI2_movavg=nanmean(EVI_period);
Imn_EVI2_avgmovall=[Imn_EVI2_avgmovall Imn_EVI2_movavg];
end

采纳的回答

Jan
Jan 2013-1-22
d = [nan;2;3;nan;4;5;nan;6;nan;nan];
idx = isnan(d);
d(idx) = 0;
result = conv(d, ones(1,7), 'same') ./ conv(double(idx), ones(1,7), 'same');
Here not all sums over 7 neighboring elements are divided by the window width 7, but by the number of not NaNs.
  1 个评论
Kemal
Kemal 2013-1-23
I see. What does the "double" command do? In the last row of the code, putting ~ before idx does the trick. Currently, it counts the number of NaNs.
Next step: How could I have the standard deviation calculated in the same fashion as the average calculation? Thank you!

请先登录,再进行评论。

更多回答(3 个)

Image Analyst
Image Analyst 2013-1-22
Assuming each element is the measurement for one day, can't you just do
movingAverage = conv(yourData, ones(1,7), 'same');
  6 个评论
Jan
Jan 2013-1-22
Btw., you need to divide by 7 in addition for a moving average:
conv(yourData, ones(1,7)/7, 'same')
Image Analyst
Image Analyst 2013-1-22
Correct. Your answer does what I was thinking, and (trying to) describe.

请先登录,再进行评论。


Gary Kuepper
Gary Kuepper 2016-11-24
Why not use movmean function?
  1 个评论
Image Analyst
Image Analyst 2016-11-24
Because when Kemal posted this almost 4 years ago, the movmean() function had not yet been introduced. Now, or actually since R2016a, you can use movmean().

请先登录,再进行评论。


nlm
nlm 2020-2-20
Hi Kemal, did you find solution to your problem ? If so can you share ?

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by