how to remove the zeros inside a 3D matrix?

3 views (last 30 days)
AA,
I have a 3D matrix
Xroot(z,w,k) (10x33x402).
The problem is, for example Xroot(1,1,:) it contians 400 zeros and just 2 needed values.
and this for most of Xroot(z,w,:).
Xroot(1,1,:)
ans(:,:,1) =
69.8033
ans(:,:,2) =
83.5743
ans(:,:,3) =
0
ans(:,:,4) =
0
ans(:,:,5) =
0
etc...
______________ % another example
Xroot(10,15,:)
...
ans(:,:,363) =
0
ans(:,:,364) =
0
ans(:,:,365) =
33.0133
ans(:,:,366) =
84.2195
ans(:,:,367) =
0
etc...
I want to extract the 2 needed values and Xroot to be (10x33x2).
Notes:
[some of Xroot(z,w) contains fully of zeros, as that means there is no solution at that z,w] so, in this case i want them to be two zeros as Xroot (10x33x2).
[Note that, not all Xroot(:,:,1:2) are the needed values, they are can be Xroot(:,:,365:366) like Xroot(10,15,:), but there are always come Consecutivly ]

Accepted Answer

Voss
Voss on 7 Jul 2022
Edited: Voss on 7 Jul 2022
Here's one way:
% a (slightly) smaller example, to demonstrate
Xroot = zeros(7,15,402);
% with a few non-zero elements in consecutive "pages" (i.e., 3rd dim)
Xroot(1,1,[11 12]) = [5 6];
Xroot(1,2,[201 202]) = [7 8];
Xroot(5,1,[301 302]) = [-9 -10];
[m,n,p] = size(Xroot);
% page_idx is the index in the 3rd dimension where the first
% non-zero element occurs in each (row,column) of Xroot
[~,page_idx] = max(logical(Xroot),[],3)
page_idx = 7×15
11 201 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 301 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
% convert those locations to linear indices
[r,c] = ndgrid(1:m,1:n);
linear_idx = sub2ind([m n p],r(:),c(:),page_idx(:))
linear_idx = 105×1
1051 2 3 4 31505 6 7 21008 9 10
% get those elements and the ones next to them in
% the next page, m*n elements later;
% reshape result into 2 columns
temp = reshape(Xroot(linear_idx+[0 m*n]),[],2)
temp = 105×2
5 6 0 0 0 0 0 0 -9 -10 0 0 0 0 7 8 0 0 0 0
% reshape to m-by-n-by-2 for final result
Xroot = reshape(temp,m,n,[]);
format compact
disp(Xroot);
(:,:,1) = 5 7 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -9 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 (:,:,2) = 6 8 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -10 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
  2 Comments
Voss
Voss on 8 Jul 2022
You're welcome!
Regarding your message, please post a new question, and someone may be able to help.

Sign in to comment.

More Answers (2)

Chunru
Chunru on 7 Jul 2022
% Xroot(z,w,k) (10x33x402).
m1 = 10; m2 = 33; m3 = 402;
m1 = 4; m2 = 5; m3 = 6;
% Generate data
Xroot = zeros(m1, m2, m3);
for i=1:m1
for j=1:m2
Xroot(i, j, randperm(m3, 2)) = rand(1,2); % 2 nonzeros
end
end
% Get the index
idx = zeros(m1, m2, 2);
val = zeros(m1, m2, 2);
for i=1:m1
for j=1:m2
[v1, i1] = sort(Xroot(i,j,:), 'descend');
idx(i,j,:) = i1(1:2);
val(i,j,:) = v1(1:2);
fprintf('i=%3d j=%3d idx: %3d %3d; val: %f %f\n', i, j, idx(i,j,:), val(i,j,:));
end
end
i= 1 j= 1 idx: 5 2; val: 0.670144 0.208733 i= 1 j= 2 idx: 2 4; val: 0.729268 0.418120 i= 1 j= 3 idx: 4 5; val: 0.644506 0.643362 i= 1 j= 4 idx: 3 6; val: 0.603974 0.202120 i= 1 j= 5 idx: 6 1; val: 0.746606 0.455431 i= 2 j= 1 idx: 3 5; val: 0.530988 0.385374 i= 2 j= 2 idx: 4 5; val: 0.745114 0.379642 i= 2 j= 3 idx: 1 2; val: 0.813252 0.653010 i= 2 j= 4 idx: 6 2; val: 0.880486 0.027366 i= 2 j= 5 idx: 4 6; val: 0.960762 0.034169 i= 3 j= 1 idx: 2 4; val: 0.395492 0.358227 i= 3 j= 2 idx: 4 6; val: 0.206305 0.127420 i= 3 j= 3 idx: 2 5; val: 0.985977 0.252404 i= 3 j= 4 idx: 2 1; val: 0.454050 0.113484 i= 3 j= 5 idx: 1 6; val: 0.848944 0.591683 i= 4 j= 1 idx: 4 6; val: 0.600984 0.133792 i= 4 j= 2 idx: 3 1; val: 0.971629 0.004523 i= 4 j= 3 idx: 3 2; val: 0.840334 0.108039 i= 4 j= 4 idx: 3 4; val: 0.374167 0.316749 i= 4 j= 5 idx: 4 3; val: 0.864410 0.842234

DGM
DGM on 7 Jul 2022
Edited: DGM on 7 Jul 2022
Assuming that each dim3 vector contains either 2 or 0 nonzero elements:
% an example array
A = cat(3,[0 0 0; 0 1 0; 5 0 0], ...
[0 3 0; 0 2 0; 6 0 0], ...
[0 4 0; 0 0 0; 0 0 0])
A =
A(:,:,1) = 0 0 0 0 1 0 5 0 0 A(:,:,2) = 0 3 0 0 2 0 6 0 0 A(:,:,3) = 0 4 0 0 0 0 0 0 0
% get nonzero elements, rearrange
Ar = nonzeros(permute(A,[3 1 2]));
Ar = reshape(Ar,2,[]).'
Ar = 3×2
5 6 3 4 1 2
% construct output array
hasroots = repmat(any(A,3),1,1,2);
B = zeros([size(A,1) size(A,2) 2]);
B(hasroots) = Ar
B =
B(:,:,1) = 0 3 0 0 1 0 5 0 0 B(:,:,2) = 0 4 0 0 2 0 6 0 0
There are probably other ways as well.

Categories

Find more on Function Creation in Help Center and File Exchange

Community Treasure Hunt

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

Start Hunting!