フィルターのクリア

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

3 ビュー (過去 30 日間)
Mr M.
Mr M. 2018 年 6 月 30 日
編集済み: Stephen23 2018 年 6 月 30 日
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?

採用された回答

Guillaume
Guillaume 2018 年 6 月 30 日
編集済み: Guillaume 2018 年 6 月 30 日
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)

その他の回答 (2 件)

Stephen23
Stephen23 2018 年 6 月 30 日
編集済み: Stephen23 2018 年 6 月 30 日
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 2018 年 6 月 30 日
編集済み: Jan 2018 年 6 月 30 日
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

カテゴリ

Help Center および File ExchangeLogical についてさらに検索

タグ

Community Treasure Hunt

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

Start Hunting!

Translated by