我有一个MxNxK大小的大型D
矩阵。给定大小为MxN的二进制掩码B
,我希望将矩阵D
拆分为两个子矩阵:D0
和D1
,使得矩阵D0
具有与二进制掩码中的0's
相关联的矩阵D
的值。这同样适用于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
欢迎所有建议;-)
在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 )
您也可以在完全没有任何循环的情况下完成此操作,方法是将2d二进制掩码复制到数据大小的3d掩码中,然后进行逻辑索引。
binmask_big = repmat(binmask, [1 1 K]);
mat_ones = matrixbig(binmask_big==1);
mat_zeros = matrixbig(binmask_big==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)];
就在那儿!