How to fill zeros and NaNs with the average of the previous nonzero consecutive values (part 2)

조회 수: 3 (최근 30일)
Hi, here's a challenge that is too hard for me and I need enlightment, a few weeks ago I posted this question:
"So, i have a column like this:
T = [0;0;1;2;3;4;NaN;4;3;0;0;0;NaN;4;2;3;0;2;0];
And everytime I have a NaN or a zero, I would like to transform them in the average of the previous nonzero consecutive values (averages in bold):
T = [0;0;1;2;3;4;2.5;4;3;3.5;3.5;3.5;3.5;4;2;3;3;2;2];
I cannot figure out how I can do this in an efficient way (without for loops, because the column has thousands of rows)."
This was the only answer I got which helped me a lot:
"Using this FEX download,
T = [0;0;1;2;3;4;NaN;4;3;0;0;0;NaN;4;2;3;0;2;0];
idx=find(T,1);
[stem,T]=deal(T(1:idx-1),T(idx:end));
G=groupTrue(~isnan(T) & T~=0);
[~,~,lengths]=groupLims(groupTrue(~G),1);
T(~G)=repelem( groupFcn(@mean,T,G) ,lengths);
T=[stem;T]
T'
"
However, I think sometime my data has too many NaNs or zeros and I get erros like this:
Error using splitapply
Group numbers must be a vector of positive integers, and cannot be a sparse vector.
Error in groupFcn (line 30)
[varargout{1:nargout}]=splitapply(func,varargin{:},G);
Error in PowerDependency (line 130)
T(~G)=repelem( groupFcn(@mean,T,G) ,lengths);
Making me think that it's risky to use these types of functions that I can't understand when I have errors (lol).
Anyways my help request is can anyone figure out another way? Doesn't have to be duper efficient and instant, I can handle a few seconds of run time, but not too much like verifying row by row :(
I would be extremely happy if someone could help, cheers!
  댓글 수: 14
dpb
dpb 2023년 4월 6일
My first foray into the fray in response to "I think sometime my data has too many NaNs or zeros and I get erros like this..." was to observe that
:I'd venture it's not enough, rather than too many. If there were an empty result that would produce the message."
"Just sayin..." <vbg>

댓글을 달려면 로그인하십시오.

답변 (1개)

Peter Perkins
Peter Perkins 2023년 4월 6일
Just for fun: a varfun soln. Would look similar using grouptransform.
Step one is to define groups of elements by finding runs of non-NaN/non-zero followed by runs of NaN/zero.
x = [0;0;1;2;3;4;NaN;4;3;0;0;0;NaN;4;2;3;0;2;0];
x(x == 0) = NaN;
i = isnan(x);
starts = [false; diff(i) < 0];
group = cumsum(starts);
T = table(x,i,starts,group)
T = 19×4 table
x i starts group ___ _____ ______ _____ NaN true false 0 NaN true false 0 1 false true 1 2 false false 1 3 false false 1 4 false false 1 NaN true false 1 4 false true 2 3 false false 2 NaN true false 2 NaN true false 2 NaN true false 2 NaN true false 2 4 false true 3 2 false false 3 3 false false 3
Step 2 is to replace NaNs with the group means.
T2 = varfun(@myFun,T,InputVariables="x",GroupIngVariable="group")
T2 = 19×3 table
group GroupCount myFun_x _____ __________ _______ 0 2 NaN 0 2 NaN 1 5 1 1 5 2 1 5 3 1 5 4 1 5 2.5 2 6 4 2 6 3 2 6 3.5 2 6 3.5 2 6 3.5 2 6 3.5 3 4 4 3 4 2 3 4 3
T.xFilled = T2.myFun_x
T = 19×5 table
x i starts group xFilled ___ _____ ______ _____ _______ NaN true false 0 NaN NaN true false 0 NaN 1 false true 1 1 2 false false 1 2 3 false false 1 3 4 false false 1 4 NaN true false 1 2.5 4 false true 2 4 3 false false 2 3 NaN true false 2 3.5 NaN true false 2 3.5 NaN true false 2 3.5 NaN true false 2 3.5 4 false true 3 4 2 false false 3 2 3 false false 3 3
function x = myFun(x)
m = mean(x,"omitmissing");
x(isnan(x)) = m;
end

카테고리

Help CenterFile Exchange에서 Data Type Conversion에 대해 자세히 알아보기

Community Treasure Hunt

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

Start Hunting!

Translated by