how to remove the zeros inside a 3D matrix?

1 次查看(过去 30 天)
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 ]

采纳的回答

Voss
Voss 2022-7-7
编辑:Voss 2022-7-7
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 个评论
Voss
Voss 2022-7-8
You're welcome!
Regarding your message, please post a new question, and someone may be able to help.

请先登录,再进行评论。

更多回答(2 个)

Chunru
Chunru 2022-7-7
% 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 2022-7-7
编辑:DGM 2022-7-7
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.

类别

Help CenterFile Exchange 中查找有关 Function Creation 的更多信息

标签

Community Treasure Hunt

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

Start Hunting!

Translated by