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

10 vues (au cours des 30 derniers jours)
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.

Réponse acceptée

Thorsten
Thorsten le 4 Déc 2014
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), :);

Plus de réponses (2)

Guillaume
Guillaume le 4 Déc 2014
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 commentaires
Guillaume
Guillaume le 4 Déc 2014
Modifié(e) : Guillaume le 4 Déc 2014
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.
Jo
Jo le 4 Déc 2014
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!

Connectez-vous pour commenter.


C.J. Harris
C.J. Harris le 4 Déc 2014
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'),:);

Catégories

En savoir plus sur Logical dans Help Center et File Exchange

Tags

Community Treasure Hunt

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

Start Hunting!

Translated by