34 views (last 30 days)

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...

Bruno Luong
on 19 Jul 2019

Edited: Bruno Luong
on 19 Jul 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))

Adam Danz
on 19 Jul 2019

Edited: Adam Danz
on 19 Jul 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

Adam Danz
on 19 Jul 2019

Sign in to comment.

Mario Chiappelli
on 19 Jul 2019

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

Mario Chiappelli
on 19 Jul 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 :)

Sign in to comment.

Sign in to answer this question.

Opportunities for recent engineering grads.

Apply Today
## 0 Comments

Sign in to comment.