【问题标题】:Pulling subsets from a large 3d matrix using a binary mask - Matlab使用二进制掩码从大型 3d 矩阵中提取子集 - Matlab
【发布时间】:2012-02-04 08:06:55
【问题描述】:

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

mat_zeros = [];
mat_ones = [];

for m=1:M
    for n=1:N

        matval = matrixbig(m,n,:);
        matval = matval(:)'; % mapping matval to a K-dimensional vector

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

欢迎所有建议 ;-)

【问题讨论】:

标签: matlab matrix indexing partitioning


【解决方案1】:

K 维度上进行迭代会产生更高效的代码,只需一个循环。请参阅下面的代码短算法部分:

% 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 )

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

    • @Matt,谢谢,但理想情况下,我希望 mat_onesmat_zeros 他们都有 K 列。按照您的建议,我得到 1 个列矩阵。
    【解决方案3】:

    最有效的方法是使用线性索引并完全避免循环。您必须预先计算掩码中 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)];
    

    你有它!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-07-21
      • 2016-11-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-30
      相关资源
      最近更新 更多