remove first s and last t rows of a matrix containing NaN, leave lows in the middle containing NaN.

I have a Tx2 Matrix A and I would like to remove the rows in the beginning and in the end that contain any NaN. For example:
A=[[NaN;NaN;NaN;4;1;NaN;5;6;8;NaN;NaN],[NaN;NaN;2;7;6;5;NaN;6;18;2;NaN]]
should the equal to:
A=[[4;1;NaN;5;6;8],[7;6;5;NaN;6;18]]
many thanks for your help, Jo.

 채택된 답변

There might be smarter solutions to figure out the indices of leading and trailing 1's in nanflag, but this solution works:
A=[[NaN;NaN;NaN;4;1;NaN;5;6;8;NaN;NaN],[NaN;NaN;2;7;6;5;NaN;6;18;2;NaN]];
nanflag = isnan(sum(A'));
ind = []; for i = 1:numel(nanflag), if nanflag(i) == 1, ind = [ind i]; else break, end, end
for i = numel(nanflag):-1:1, if nanflag(i) == 1, ind = [ind i]; else break, end, end
Anew = A(setdiff(1:size(A,1), ind), :);

추가 답변 (2개)

A=[[NaN;NaN;NaN;4;1;NaN;5;6;8;NaN;NaN],[NaN;NaN;2;7;6;5;NaN;6;18;2;NaN]];
removestart = logical(sum(cumprod(isnan(A)), 2));
removeend = flipud(logical(sum(cumprod(flipud(isnan(A))), 2)));
A(removestart | removeend, :) = []

댓글 수: 3

When I enter this code I get the Error: "Error using cumprod CUMPROD is only supported for floating point input."
Works fine on R2014b, which version are you using?
In any case if cumprod does not accept logical, just convert them to double:
A=[[NaN;NaN;NaN;4;1;NaN;5;6;8;NaN;NaN],[NaN;NaN;2;7;6;5;NaN;6;18;2;NaN]];
nanpos = double(isnan(A));
removestart = logical(sum(cumprod(nanpos), 2));
removeend = logical(sum(cumprod(nanpos, 'reverse'), 2));
A(removestart | removeend, :) = []
I've also simplify the calculation of removeend. I didn't realise that cumprod had a reverse option.
Shame you accepted a less efficient code.
I am using R2012b, this may be the cause. For anyone having the same version, adding double(..) helps, this adapted code works for me:
A=[[NaN;NaN;NaN;4;1;NaN;5;6;8;NaN;NaN],[NaN;NaN;2;7;6;5;NaN;6;18;2;NaN]];
nanpos = double(isnan(A));
removestart = logical(sum(cumprod(nanpos), 2));
removeend = flipud(logical(sum(cumprod(flipud(nanpos)), 2)));
A(removestart | removeend, :) = []
Thanks a lot!

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

Nobody should ever need more than one line:
A = [[NaN;NaN;NaN;4;1;NaN;5;6;8;NaN;NaN],[NaN;NaN;2;7;6;5;NaN;6;18;2;NaN]];
A2 = A(find(~any(isnan(A),2),1,'first'):find(~any(isnan(A),2),1,'last'),:);

카테고리

도움말 센터File Exchange에서 Logical에 대해 자세히 알아보기

태그

질문:

Jo
2014년 12월 4일

답변:

2014년 12월 4일

Community Treasure Hunt

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

Start Hunting!

Translated by