Computing a running average of a simple 1-D data vector seems simple enough. Indeed, the MATLAB开发者_开发技巧 documentation for FILTER happily claims something like:
You can use filter to find a running average without using a for loop. This example finds the running average of a 16-element vector, using a window size of 3:
D = [1:0.2:4]';
windowSize = 3;
F = ones(1,windowSize)/windowSize;
Df = filter(F,1,D);
The result:
Image of raw and filtered data plot from above example http://www.tc.umn.edu/~vande642/pictures/untitled.png
For my purposes, there are two annoying things about this result: output point n is the average of input points n-(windowSize-1)..n (i.e. not centered, as evidenced by the horizontal shift) and points to the left of the available data are treated as zeros.
FILTFILT deals with both issues, but has other drawbacks. It's part of the Signal Processing Toolbox, and it doesn't deal well with NaNs (which I'd like excluded from the mean).
Some people on FEX obviously had the same frustrations, but it seems odd to me that something this simple requires custom code. Anything I'm missing here?
You can also do a running average using convolution. Thus, you don't need to worry about filtfilt.
For example, you could use
D = [1:0.2:4];
windowSize = 3;
F = ones(1,windowSize)/windowSize;
Df = conv(D,F);
%# if you didn't use 'valid', Df is larger than D. To correct:
halfSize = floor(windowSize/2);
Df = Df(halfSize+1:end-halfSize);
Of course, you'd still have to deal with the edge, so you should pad D first, or run conv with the 'valid' argument. For example, you could use PADARRAY if you have the image processing toolbox.
The simplest way to pad would be to replicate the first and last values. If you know more about your data, other approaches can turn out to be more suited.
精彩评论