I have large vectors, containing quite a lot of NaN samples. I want to know the length of each array of NaNs within this vector, even when this equals 1. So I want to have the lenght of all NaN segments.
Thanks in advance!

1 件のコメント

Stephen23
Stephen23 2019 年 2 月 22 日
Note to future readers: the accepted answer fails for many simple cases:
Only NaN
>> A = [NaN,NaN,NaN,NaN];
>> index=find(isnan(A));
>> idx=find(diff(index)~=1);
>> R=[idx(1) diff(idx) numel(index)-idx(end)]
Attempted to access idx(1); index out of bounds because numel(idx)=0.
Only Numbers
>> A = [1,2,3,4];
>> index=find(isnan(A));
>> idx=find(diff(index)~=1);
>> R=[idx(1) diff(idx) numel(index)-idx(end)]
Attempted to access idx(1); index out of bounds because numel(idx)=0.
Empty Vector
>> A = [];
>> index=find(isnan(A));
>> idx=find(diff(index)~=1);
>> R=[idx(1) diff(idx) numel(index)-idx(end)]
Attempted to access idx(1); index out of bounds because numel(idx)=0.
Leading Numbers
>> A = [1,NaN,NaN,NaN];
>> index=find(isnan(A));
>> idx=find(diff(index)~=1);
>> R=[idx(1) diff(idx) numel(index)-idx(end)]
Attempted to access idx(1); index out of bounds because numel(idx)=0.
Trailing Numbers
>> A = [NaN,NaN,NaN,1];
>> index=find(isnan(A));
>> idx=find(diff(index)~=1);
>> R=[idx(1) diff(idx) numel(index)-idx(end)]
Attempted to access idx(1); index out of bounds because numel(idx)=0.

サインインしてコメントする。

 採用された回答

madhan ravi
madhan ravi 2019 年 2 月 21 日
編集済み: madhan ravi 2019 年 2 月 21 日

1 投票

9 件のコメント

madhan ravi
madhan ravi 2019 年 2 月 21 日
A = [NaN NaN NaN 1 2 3 4 NaN 3 44 NaN] ; % example data
index=find(~isnan(A)); % will give you the length of numbers inbetween nan , if you remove ~ it will give the length of nans inbetween numbers
idx=find(diff(index)~=1);
R=[idx(1) diff(idx) numel(index)-idx(end)]
Lieke Numan
Lieke Numan 2019 年 2 月 21 日
Thanks a lot!
madhan ravi
madhan ravi 2019 年 2 月 21 日
編集済み: madhan ravi 2019 年 2 月 21 日
Jos did you read the comment first? Just remove ~ infront of isnan() please examine before flagging.
Jos (10584)
Jos (10584) 2019 年 2 月 21 日
My apologies, I will remove the flag and comment.
Stephen23
Stephen23 2019 年 2 月 22 日
編集済み: Stephen23 2019 年 2 月 22 日
Note that this answer fails in many simple cases, e.g.:
All NaN
>> A = [NaN,NaN,NaN,NaN];
>> index=find(isnan(A));
>> idx=find(diff(index)~=1);
>> R=[idx(1) diff(idx) numel(index)-idx(end)]
Attempted to access idx(1); index out of bounds because numel(idx)=0.
No NaN
>> A = [1,2,3,4];
>> index=find(isnan(A));
>> idx=find(diff(index)~=1);
>> R=[idx(1) diff(idx) numel(index)-idx(end)]
Attempted to access idx(1); index out of bounds because numel(idx)=0.
Empty Vector
>> A = [];
>> index=find(isnan(A));
>> idx=find(diff(index)~=1);
>> R=[idx(1) diff(idx) numel(index)-idx(end)]
Attempted to access idx(1); index out of bounds because numel(idx)=0.
Leading Numbers
>> A = [1,NaN,NaN,NaN];
>> index=find(isnan(A));
>> idx=find(diff(index)~=1);
>> R=[idx(1) diff(idx) numel(index)-idx(end)]
Attempted to access idx(1); index out of bounds because numel(idx)=0.
Trailing Numbers
>> A = [NaN,NaN,NaN,1];
>> index=find(isnan(A));
>> idx=find(diff(index)~=1);
>> R=[idx(1) diff(idx) numel(index)-idx(end)]
Attempted to access idx(1); index out of bounds because numel(idx)=0.
Its use of indexing means that any special cases will need to be handled separately.
See my answer for simpler code that works for all of these cases.
madhan ravi
madhan ravi 2019 年 2 月 22 日
Just an if condition should suffice that need.
Stephen23
Stephen23 2019 年 2 月 22 日
編集済み: Stephen23 2019 年 2 月 22 日
"Just an if condition should suffice that need. "
Please show exactly how one simple IF statement would fix those cases.
madhan ravi
madhan ravi 2019 年 2 月 22 日
Turns out not possible :D.
madhan ravi
madhan ravi 2019 年 2 月 22 日
@Lieke there are so many limitations to this answer , you have accepted the wrong answer ;-)

サインインしてコメントする。

その他の回答 (3 件)

Stephen23
Stephen23 2019 年 2 月 21 日
編集済み: Stephen23 2019 年 2 月 22 日

1 投票

This is simpler and actually works for all horizontal vectors (unlike the accepted answer):
>> A = [NaN NaN NaN 1 2 3 4 NaN 3 44 NaN];
>> D = diff([false,isnan(A),false]);
>> find(D<0)-find(D>0)
ans =
3 1 1
For a slightly faster version you can call find once:
>> F = find(diff([false,isnan(A),false]));
>> F(2:2:end)-F(1:2:end)
ans =
3 1 1
EDIT: uses Jan's logical vector suggestion.

8 件のコメント

madhan ravi
madhan ravi 2019 年 2 月 21 日
編集済み: madhan ravi 2019 年 2 月 21 日
Even the accepted answer works as mentioned exactly in the comment.
madhan ravi
madhan ravi 2019 年 2 月 21 日
I accept it's simpler than the accepted answer but I don't think it's faster:
>> A = [NaN NaN NaN 1 2 3 4 NaN 3 44 NaN];
tic
for k=1:1e5
D = diff([0,isnan(A),0]);
find(D<0)-find(D>0);
end
toc
tic
for k=1:1e5
index=find(isnan(A));
idx=find(diff(index)~=1);
R=[idx(1) diff(idx) numel(index)-idx(end)];
end
toc
Elapsed time is 1.533159 seconds.
Elapsed time is 0.308740 seconds.
>>
Jos (10584)
Jos (10584) 2019 年 2 月 21 日
A diff-find-diff solution :-D
D = diff(find(diff([0,isnan(A),0])))
R = D(1:2:end)
Stephen23
Stephen23 2019 年 2 月 22 日
"Even the accepted answer works as mentioned exactly in the comment."
Except when it doesn't work:
madhan ravi
madhan ravi 2019 年 2 月 22 日
Stephen23
Stephen23 2019 年 2 月 22 日
madhan ravi
madhan ravi 2019 年 2 月 22 日
Yes but in this thread :D.
Stephen23
Stephen23 2019 年 2 月 22 日
"Yes but in this thread "
The main difference is swapping == for isnan (which everyone used). I doubt that it makes much difference, but you are welcome to do some tests and post the results here.

サインインしてコメントする。

Jan
Jan 2019 年 2 月 22 日
編集済み: Jan 2019 年 2 月 22 日

1 投票

And again: With FEX: RunLength :
[B, N] = RunLength(A);
Result = N(isnan(B));
Or:
y = [false, isnan(A), false];
Result = strfind(y, [true, false]) - strfind(y, [false,true])
For this test vector:
A = ones(1, 1e5);
A(randperm(1e5, 5e4)) = NaN;
the method posted by Jos (link) is about 10% faster:
D = diff(find(diff([false, isnan(A), false])));
R = D(1:2:end);
KSSV
KSSV 2019 年 2 月 21 日

0 投票

Read about isnan and nnz

4 件のコメント

madhan ravi
madhan ravi 2019 年 2 月 21 日
nnz will give you the total number of elements not the length of each array of nans
KSSV
KSSV 2019 年 2 月 21 日
A = [NaN NaN NaN 1 2 3 4 NaN] ;
nnz(isnan(A))
There are four NaN's.
madhan ravi
madhan ravi 2019 年 2 月 21 日
編集済み: madhan ravi 2019 年 2 月 21 日
OP wants it like 3 nans and 1 nan not the total number of nans or the length of each numbers inbetween nans.
KSSV
KSSV 2019 年 2 月 21 日
he can use diff anddo that..

サインインしてコメントする。

カテゴリ

ヘルプ センター および File ExchangeLarge Files and Big Data についてさらに検索

タグ

Community Treasure Hunt

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

Start Hunting!

Translated by