Find first non-NaN in each column of array & combine into one vector

19 visualizaciones (últimos 30 días)
I am trying to:
1) Identify the first non-NaN value of each column in an array, and convert the rest to NaN
2) Identify the first non-NaN value of each row in the array, and convert the rest to NaN
3) Combine these numbers back into one column vector
I have created something that looks roughly like this (although much larger):
X =
2 NaN NaN NaN
4 6 NaN NaN
NaN NaN NaN NaN
5 4 7 8
After the first step (keeping only the first number in each column), I would hope to have this:
Xa =
2 NaN NaN NaN
NaN 6 NaN NaN
NaN NaN NaN NaN
NaN NaN 7 8
After the second step (keeping only the first number in each row), I would hope to have this:
Xb =
2 NaN NaN NaN
NaN 6 NaN NaN
NaN NaN NaN NaN
NaN NaN 7 NaN
Lastly, I would want to turn this into one column (there should only be NaN's or 1 non-NaN value in each row - I would want it to keep whichever is there)
Xc =
2
6
NaN
7
I apologize for not having any attempted code for this. I appear to have gotten stuck in the doorway of this one...

Respuesta aceptada

Bruno Luong
Bruno Luong el 19 de Jul. de 2019
Editada: Bruno Luong el 19 de Jul. de 2019
X = [2 NaN NaN NaN;
4 6 NaN NaN;
NaN NaN NaN NaN;
5 4 7 8 ]
[m,n] = size(X);
[I,J] = ndgrid(1:m,1:n);
Xa = X;
[~,r]=max(isfinite(Xa),[],1);
Xa(I>r) = NaN
Xb = Xa;
[~,c]=max(isfinite(Xb),[],2);
Xb(J>c) = NaN
[~,c]=max(isfinite(Xb),[],2);
Xc = Xb(sub2ind([m,n],(1:m)',c))
  2 comentarios
mfclose
mfclose el 19 de Jul. de 2019
Thank you, this did exactly what I needed!
Adam Danz
Adam Danz el 19 de Jul. de 2019
Editada: Adam Danz el 19 de Jul. de 2019
Be sure to add semicolons to the end of 3 lines that are missing them.
Also, use ~isnan() rather than isfinite().

Iniciar sesión para comentar.

Más respuestas (2)

Adam Danz
Adam Danz el 19 de Jul. de 2019
Editada: Adam Danz el 19 de Jul. de 2019
X = [2 NaN NaN NaN
4 6 NaN NaN
NaN NaN NaN NaN
5 4 7 8];
X(cumsum(cumsum(~isnan(X)))~=1) = NaN; % your Xa
X(cumsum(cumsum(~isnan(X),2),2) ~=1) = NaN; % your Xb
Xc = NaN(size(X,1),1);
Xc(any(~isnan(X),2)) = X(~isnan(X)); % your Xc
  2 comentarios
mfclose
mfclose el 19 de Jul. de 2019
Thank you this also worked!
Adam Danz
Adam Danz el 19 de Jul. de 2019
Editada: Adam Danz el 19 de Jul. de 2019
Glad I could help! Just FYI, this solution and the max(infinite()) solution are both quite fast but this one is 4.5x faster (10,000 iterations, p<0.0001 Wicoxon signed rank) with less overhead. Also, instead of isfinite(), you should use ~isnan().

Iniciar sesión para comentar.


Mario Chiappelli
Mario Chiappelli el 19 de Jul. de 2019
Check out this question asked earlier on the forum, I think it asks and answers what you want.
  3 comentarios
Mario Chiappelli
Mario Chiappelli el 19 de Jul. de 2019
Try this:
x = [2,NaN,NaN,NaN;4,6,NaN,NaN;NaN,NaN,NaN,NaN;5,4,7,8];
rows = length(x(:,1));
columns = length(x(1,:));
% This finds the first non NaN in the columns
columnVector = double(columns);
for i = 1:columns
found = 0;
for j = 1:rows
if ~isnan(x(j,i)) && found == 0
found = 1;
columnVector(i) = x(j,i);
end
end
if found == 0
columnVector(i) = NaN;
end
end
% This finds the first non NaN in the rows
rowVector = double(rows);
for i = 1:rows
found = 0;
for j = 1:columns
if ~isnan(x(i,j)) && found == 0
found = 1;
rowVector(i) = x(i,j);
end
end
if found == 0
rowVector(i) = NaN;
end
end
I could include some more functionality to delete any NaN values in the resulting columnVector and rowVector arrays. This does what you want, however it skips over the middle steps. I did not know if that was a necessary step for you or just your way of visualizing what needed to be done.
Hope this helps :)
mfclose
mfclose el 19 de Jul. de 2019
This was very close, but I did need the middle step getting rid of the other non-NaN values in a column. The code below fixed this. Thank you so much for helping!

Iniciar sesión para comentar.

Categorías

Más información sobre Block Libraries en Help Center y File Exchange.

Community Treasure Hunt

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

Start Hunting!

Translated by