MATLAB Answers

mfclose
0

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

mfclose
さんによって質問されました 2019 年 7 月 19 日
最新アクティビティ Adam Danz
さんによって 編集されました 2019 年 7 月 19 日
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...

  0 件のコメント

サインイン to comment.

3 件の回答

回答者: Bruno Luong
2019 年 7 月 19 日
編集済み: Bruno Luong
2019 年 7 月 19 日
 採用された回答

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 件のコメント

mfclose
2019 年 7 月 19 日
Thank you, this did exactly what I needed!
Adam Danz
2019 年 7 月 19 日
Be sure to add semicolons to the end of 3 lines that are missing them.
Also, use ~isnan() rather than isfinite().

サインイン to comment.


回答者: Adam Danz
2019 年 7 月 19 日
編集済み: Adam Danz
2019 年 7 月 19 日

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 件のコメント

mfclose
2019 年 7 月 19 日
Thank you this also worked!
Adam Danz
2019 年 7 月 19 日
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().

サインイン to comment.


回答者: Mario Chiappelli 2019 年 7 月 19 日

Check out this question asked earlier on the forum, I think it asks and answers what you want.

  3 件のコメント

mfclose
2019 年 7 月 19 日
Thank you for this!
It is a similar question. Some of the differences that are proving problematic for me are that:
1) I only want the first non-NaN value, not all of them
2) I don't want to lose the row position that each of these values have (as that represents a time point I will need to compare back to later), so if there is only ever a NaN in a row, I need to keep that there (like in the 3rd row of Xc in my example)
These may only be subtle differences, but I'm not quite sure how to make those adjustments. Thanks for your help!
Mario Chiappelli 2019 年 7 月 19 日
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
2019 年 7 月 19 日
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!

サインイン to comment.



Translated by