필터 지우기
필터 지우기

How to create 2D matrix from 3D without a loop?

조회 수: 1 (최근 30일)
Humza  Khan
Humza Khan 2019년 12월 4일
댓글: Humza Khan 2019년 12월 4일
I have an n x m x 3 matrix A and an n x m matrix B. B contains the values 1, 2, or 3, referring to the three different layers in A. I want to create another n x m matrix C where each point is the value of A from the layer specified by B. For instance, if A(1,1,:) = [8 6 5], B(1,1) = 2, then C(1,1) = 6, because B at that point specifies taking from the second layer. I know how to do this with a loop, but I was wondering if there was an easier, vectorized way to do so. Thanks!

채택된 답변

Andrei Bobrov
Andrei Bobrov 2019년 12월 4일
[n,m,k] = size(A);
[i,j] = ndgrid(1:n,1:m);
C = A(sub2ind([n,m,k],i,j,B);

추가 답변 (1개)

Thomas Satterly
Thomas Satterly 2019년 12월 4일
Here's one way to do it with vectorized code. Calculating the column index list can probably be done better, but it gets the idea across
A = rand(4, 3, 6);
B = [1 2 3; 2 3 4; 3 4 5; 4 5 6];
% List of row indicies
rows = repmat(1:size(B, 1), 1, size(B, 2));
% List of column indicies, probably a better way to do this
cols = repmat(1:size(B, 2), 1, size(B, 1));
cols = reshape(reshape(cols, [size(B, 2), size(B, 1)])', 1, numel(cols));
% Convert row/col to index
inds = sub2ind(size(A), rows, cols, B(:)');
% Get the new matrix with vectorized code
C_vectorized = reshape(A(inds), size(B));
% Get new matrix with loops
C_looped = zeros(size(B));
for i = 1:size(B, 1)
for j = 1:size(B, 2)
C_looped(i, j) = A(i, j, B(i, j));
end
end
% Make sure they're the same
matched = C_vectorized == C_looped;
assert(all(matched(:)), 'Matricies do not match\n');
  댓글 수: 1
Stephen23
Stephen23 2019년 12월 4일
Simpler way to make sure that they are the same:
isequal(C_vectorized,C_looped)

댓글을 달려면 로그인하십시오.

카테고리

Help CenterFile Exchange에서 Multidimensional Arrays에 대해 자세히 알아보기

Community Treasure Hunt

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

Start Hunting!

Translated by