使用二进制掩码从大型三维矩阵中提取子集 - Matlab

时间:2012-01-06 15:48:52

标签: matlab matrix indexing partitioning

我有一个大的D矩阵,大小为MxNxK。给定大小为MxN的二进制掩码B,我想将矩阵D拆分为两个子矩阵:D0D1,以矩阵{{1}的方式}}具有与二进制掩码中的D0关联的矩阵D的值。这同样适用于0's,但在二进制掩码中使用D1。 目前,我正在通过使用循环解决这个问题,但我想知道是否有更有效的方法来解决这个问题?

1's

欢迎所有建议; - )

3 个答案:

答案 0 :(得分:1)

迭代K维度会导致只有一个循环的更高效代码。请参阅以下代码的 Shorter algorithm 部分:

% Some data
clear; M = 3; N = 2; K = 4;
matrixbig = rand(M,N,K);
binmask = round(matrixbig(:,:,1));

% Original algorithm
mat_zeros = []; mat_ones = [];
for m=1:M
  for n=1:N
    matval = matrixbig(m,n,:);
    matval = matval(:)';

    if (binmask(m,n) == 1)
      mat_ones   = [mat_ones; matval];
    elseif (binmask(m,n) == 0)
      mat_zeros   = [mat_zeros; matval];
    end
  end
end 

% Shorter algorithm
mat_zeros1 = []; mat_ones1 = [];
mask = (binmask == 1)';
for k = 1:K
  matval = matrixbig(:,:,k)';
  mat_ones1  = [mat_ones1,  matval(mask)];
  mat_zeros1 = [mat_zeros1, matval(~mask)];
end

% Compare results of two algorithms
isequal(mat_ones,  mat_ones1 )
isequal(mat_zeros, mat_zeros1 )

答案 1 :(得分:1)

您也可以在没有任何循环的情况下执行此操作,方法是将2d二进制掩码复制到数据大小的3d掩码中,然后进行逻辑索引。

binmask_big = repmat(binmask, [1 1 K]);
mat_ones = matrixbig(binmask_big==1);
mat_zeros = matrixbig(binmask_big==0);

答案 2 :(得分:0)

最有效的方法是使用线性索引并完全避免循环。您必须预先计算掩码中的1和0索引。以下应该有效:

% You must define M,N in order for the code to work

mat_zeros = [];
mat_ones = [];

indOnes=find(binmask==1);  %returns linear indices
indZeros=find(binmask==0); %returns linear indices

mat_ones   = [matrixbig(indOnes) matrixbig(indOnes+M*N) matrixbig(indOnes+2*M*N)];
mat_zeros  = [matrixbig(indZeros) matrixbig(indZeros+M*N) matrixbig(indZeros+2*M*N)];

你有它!