How count NaN values and replace NaNs in a sequence with that number?

1 Ansicht (letzte 30 Tage)
I have a vector [0 0 NaN 0 0 NaN NaN NaN 0 0 0 0 0 NaN] and I want [0 0 1 0 0 3 3 3 0 0 0 0 0 1]. Is it possible without a for cycle?

Akzeptierte Antwort

Guillaume
Guillaume am 30 Jun. 2018
Bearbeitet: Guillaume am 30 Jun. 2018
I don't think it's entirely possible to do it without a loop, but the loop can be limited to the number of sequences (3 steps in your example)
v = [0 0 NaN 0 0 NaN NaN NaN 0 0 0 0 0 NaN];
seqedges = find(diff([false, isnan(v), false]));
seqstarts = seqedges(1:2:end);
seqends = seqedges(2:2:end);
seqlengths = seqends - seqstarts;
for seq = 1:numel(seqstarts)
v(seqstarts(seq):seqends(seq)-1) = seqlengths(seq);
end
edit: actually, it's possible without a loop:
v = [0 0 NaN 0 0 NaN NaN NaN 0 0 0 0 0 NaN];
nanlocs = isnan(v);
seqedges = find(diff([false, nanlocs, false]));
seqlengths = seqedges(2:2:end) - seqedges(1:2:end);
v(nanlocs) = repelem(seqlengths, seqlengths)

Weitere Antworten (2)

Stephen23
Stephen23 am 30 Jun. 2018
Bearbeitet: Stephen23 am 30 Jun. 2018
No loops, no third-party functions, and works for all MATLAB versions:
>> V = [0 0 NaN 0 0 NaN NaN NaN 0 0 0 0 0 NaN];
>> X = isnan(V);
>> Y = cumsum(diff([0,X])>0);
>> D = diff([0,X,0]);
>> L = find(D<0)-find(D>0);
>> V(X) = L(Y(X))
V = 0 0 1 0 0 3 3 3 0 0 0 0 0 1

Jan
Jan am 30 Jun. 2018
Bearbeitet: Jan am 30 Jun. 2018
With FEX: RunLength (link):
a = [0 0 NaN 0 0 NaN NaN NaN 0 0 0 0 0 NaN];
[b, n] = RunLength(isnan(a));
Result = RunLength(b .* n, n);
The C-Mex version runs very fast, but you have to compile it at first. But you can use the M-version included in this submission also: RunLength_M

Kategorien

Mehr zu Video games finden Sie in Help Center und File Exchange

Tags

Community Treasure Hunt

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

Start Hunting!

Translated by