I am trying to compute a moving average on multiple columns of a matrix. After reading some answers on stackoverflow, namely this one, it seemed that the filter function was the way to go. However, it does not ignore NaN elements, and I would like to do this ignoring NaN elements in the spirit of the function nanmean. Below a sample code:
X = rand(100,100); %generate sample matrix
X(sort(randi([1 100],1,10)),sort(randi([1 100],1,10))) = NaN; %put some random NaNs
windowlenght = 7;
MeanMA = filter(ones(1, windowlenght) / windowlenght, 1, X);
Use colfilt with nanmean:
>> A = [1 2 3 4 5; 2 nan nan nan 6; 3 nan nan nan 7; 4 nan nan nan 8; 5 6 7 8 9]
A =
1 2 3 4 5
2 NaN NaN NaN 6
3 NaN NaN NaN 7
4 NaN NaN NaN 8
5 6 7 8 9
>> colfilt(A, [3,3], 'sliding', @nanmean)
ans =
0.6250 1.1429 1.5000 2.5714 1.8750
1.1429 2.2000 3.0000 5.0000 3.1429
1.5000 3.0000 NaN 7.0000 3.5000
2.5714 5.0000 7.0000 7.8000 4.5714
1.8750 3.1429 3.5000 4.5714 3.1250
(if you only care about 'full' blocks, select inner rows / columns appropriately)
Alternatively, you can also use nlfilter, but you then need to be explicit (via an anonymous function handle) about what you'll be doing with the block; in particular, to work with nanmean such that it will produce a scalar output from the whole block, you'll need to convert each block to a column-vector before calling nanmean in your anonymous function:
>> nlfilter(A, [3,3], @(x) nanmean(x(:)))
ans =
0.6250 1.1429 1.5000 2.5714 1.8750
1.1429 2.2000 3.0000 5.0000 3.1429
1.5000 3.0000 NaN 7.0000 3.5000
2.5714 5.0000 7.0000 7.8000 4.5714
1.8750 3.1429 3.5000 4.5714 3.1250
However, for the record, matlab claims colfilt will generally be faster, so generally nlfilter is better reserved for situations where it doesn't make sense for your input to be converted to a column when processing each block.
Also see matlab's manual page/chapter on sliding operations in general.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With