find length NaN segments
古いコメントを表示
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
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.
採用された回答
その他の回答 (3 件)
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
2019 年 2 月 21 日
編集済み: madhan ravi
2019 年 2 月 21 日
Even the accepted answer works as mentioned exactly in the comment.
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)
2019 年 2 月 21 日
A diff-find-diff solution :-D
D = diff(find(diff([0,isnan(A),0])))
R = D(1:2:end)
Stephen23
2019 年 2 月 22 日
"Even the accepted answer works as mentioned exactly in the comment."
Except when it doesn't work:
madhan ravi
2019 年 2 月 22 日
Stephen23
2019 年 2 月 22 日
Faster, although not as fast as Jan's STRFIND solution:
madhan ravi
2019 年 2 月 22 日
Yes but in this thread :D.
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.
[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;
D = diff(find(diff([false, isnan(A), false])));
R = D(1:2:end);
KSSV
2019 年 2 月 21 日
0 投票
Read about isnan and nnz
4 件のコメント
madhan ravi
2019 年 2 月 21 日
nnz will give you the total number of elements not the length of each array of nans
KSSV
2019 年 2 月 21 日
A = [NaN NaN NaN 1 2 3 4 NaN] ;
nnz(isnan(A))
There are four NaN's.
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
2019 年 2 月 21 日
he can use diff anddo that..
カテゴリ
ヘルプ センター および File Exchange で Large Files and Big Data についてさらに検索
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!