# How to return a 2D matrix containing the heighest non-NaN values from a 3D matrix

2 views (last 30 days)
Steven on 28 Oct 2013
Edited: Andrei Bobrov on 29 Oct 2013
Hi,
I have a large 3D matrix of data where in the 3rd dimension where some values are NaN and some values are non-NaN. Call it M with size m*n*p.
A 2D matrix P (size m*n) contains the number of non-NaN values held within the pages returned in the array M(m,n).
Also, take one value of P, t=P(m,n); then each of M(m,n,1:t) contains a non-NaN value, and each of M(m,n,t+1:end) contains a NaN value. That is, all the non-NaN values in M are stacked from the p=1 to p=nth pages.
An example of the data is created with this code:
P = ceil(rand(4,4) * 4);
for x = 1:4
for y = 1:4
for z = 1:4
if P(x,y) >= z
M(x,y,z) = ceil(rand*10);
else
M(x,y,z) = NaN;
end
end
end
end
For example:
M(:,:,1) =
9 10 4 4
10 4 10 3
3 3 10 9
3 8 5 9
M(:,:,2) =
9 NaN NaN 3
6 NaN 9 3
6 3 7 4
8 4 9 8
M(:,:,3) =
4 NaN NaN 9
5 NaN NaN NaN
10 NaN 10 4
8 NaN 4 4
M(:,:,4) =
NaN NaN NaN 9
7 NaN NaN NaN
1 NaN 2 NaN
2 NaN 10 NaN
I am looking for an efficient way to return the 'pth-most' values of M, which is essentially the last non-NaN value of each M(m,n) array. For the example dataset this would be:
result =
4 10 4 9
7 4 9 3
1 3 2 4
2 4 10 4
Does anyone have any clever suggestions?
Thank you Steven

Andrei Bobrov on 28 Oct 2013
Edited: Andrei Bobrov on 29 Oct 2013
s = size(M);
[i1,i2] = ndgrid(1:s(1),1:s(2));
result = M(sub2ind(s,i1,i2,s(3) - sum(isnan(M),3)));
s = size(M);
[i1,i2] = ndgrid(1:s(1),1:s(2));
i3 = s(3) - sum(isnan(M),3);
i3(i3==0)=1;
result = M(sub2ind(s,i1,i2,i3));

Steven on 29 Oct 2013
Great thank you!
Steven on 29 Oct 2013
I wonder if you can help me further; how would you handle the situation where some of the arrays returned by M(m,n) are entirely NaN's?
In this instance, sum(isnan(M),3) == s(3), and the sub2ind function call will be badly formed?
Andrei Bobrov on 29 Oct 2013