Weighted average between NaNs with movmean, determing window length?

8 次查看(过去 30 天)
I am trying to calculated a weighted average using movmean that takes the values between NaNs in a column of data. However, I the number of elements between NaNs, and the number of consecutive NaNs varies throughout the dataset.
For instance, one column of data may look like [1, 3 ,2 ,5 , NaN, NaN, 1, NaN, NaN, NaN, NaN, 4, 4, 7, 1, 3, NaN, 2, 5, 2, 3].
After reading through the documentation, I am still confused as to the proper window length settings, as the number of elements will change throughout the column.
If I set it to say, 3, I will get averages that I am not interested in (e.g. I don't need the average of 1,3,2 and 3,2,5).
Sorry if this is a simple question!
  3 个评论
JM
JM 2019-9-6
Hello,
I would like the final output to be a single value that is a moving average which weights the averages of each group of data between the NaNs. I.e. the 2.75 would be weighted proportionaly to the number of values, so that (for instance) the 1 wouldn't skew the average.
Hope that makes sense.
Adam Danz
Adam Danz 2019-9-6
What you're asking for isn't exactly a moving average which usually consists of a set window size. In any case, if you want the average of each segment between NaN values, then the output will have n values where n is the number of segments.
"the 2.75 would be weighted proportionaly to the number of values"
That's what an average does in the first place. How would you like to add additional weights?

请先登录,再进行评论。

回答(3 个)

the cyclist
the cyclist 2019-9-6
If my guess above is correct, then
input = [1, 3 ,2 ,5 , NaN, NaN, 1, NaN, NaN, NaN, NaN, 4, 4, 7, 1, 3, NaN, 2, 5, 2, 3];
[B, N, BI] = RunLength(not(isnan(input)));
N = N(B);
BI = BI(B);
numberSeq = numel(N);
inputMovMean = zeros(numberSeq,1);
for ns = 1:numberSeq
inputMovMean(ns) = mean(input(BI(ns):BI(ns)+N(ns)-1));
end
You'll need to download the nice RunLength utility from the File Exchange.

Adam Danz
Adam Danz 2019-9-6
编辑:Adam Danz 2019-9-6
This approach breaks up the vector x into a cell array of non-nan segments and then calculates the mean of each segment. xMeans(i) is the mean of the i_th non-nan segment which is stored in xSplit{i}.
% inputs
x = [1, 3 ,2 ,5 , NaN, NaN, 1, NaN, NaN, NaN, NaN, 4, 4, 7, 1, 3, NaN, 2, 5, 2, 3];
xdiff = diff(isnan([nan,x,nan])); % -1 is start of non-nan, +1 is start of NaN, 0 is no change
nonNanLengths = find(xdiff==1) - find(xdiff==-1); %lenght of each non-nan segment
xSplit = mat2cell(x(~isnan(x)),1,nonNanLengths); %cell array conaining non-nan segments
xMeans = cellfun(@mean, xSplit); %means of each segment
Result
xMeans =
2.75 1 3.8 3

the cyclist
the cyclist 2019-9-6
You really lost me when you commented that the output would be a single value. How is that a moving average? Do you just want the average of the non-NaN values? Then, it as simple as
nanmean(input)
  1 个评论
Adam Danz
Adam Danz 2019-9-6
or for those without the stats toolbox
mean(x,'omitnan') % for r2015a and later
mean(x(~isnan(x))) % for earlier version (and later)

请先登录,再进行评论。

类别

Help CenterFile Exchange 中查找有关 NaNs 的更多信息

Community Treasure Hunt

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

Start Hunting!

Translated by