如何在MATLAB中使用2-D掩模索引3-D矩阵?

Mat*_*umi 13 indexing matlab matrix

假设我有D,一个X-by-Y-by-Z数据矩阵.我也有M,一个X-by-Y"掩蔽"矩阵.我的目标是当M中的(Xi,Yi)为假时,将D中的元素(Xi,Yi,:)设置为NaN.

有没有办法避免在循环中这样做?我尝试使用ind2sub,但失败了:

M = logical(round(rand(3,3))); % mask
D = randn(3,3,2); % data

% try getting x,y pairs of elements to be masked
[x,y] = ind2sub(size(M),find(M == 0));
D_masked = D;
D_masked(x,y,:) = NaN; % does not work!

% do it the old-fashioned way
D_masked = D;
for iX = 1:size(M,1)
    for iY = 1:size(M,2)
        if ~M(iX,iY), D_masked(iX,iY,:) = NaN; end
    end
end
Run Code Online (Sandbox Code Playgroud)

我怀疑我在这里遗漏了一些明显的东西.(:

gno*_*ice 13

您可以通过M使用REPMAT在第三维上复制逻辑掩码来实现此目的,以使其大小相同D.然后,索引:

D_masked = D;
D_masked(repmat(~M,[1 1 size(D,3)])) = NaN;
Run Code Online (Sandbox Code Playgroud)

如果不希望复制掩模矩阵,则存在另一种替代方案.您可以首先找到一组线性索引,其中M等于0,然后复制该设置size(D,3)时间,然后将每组索引移动倍数,numel(M)以便索引D第三维中的不同部分.我将在这里使用BSXFUN来说明这一点:

D_masked = D;
index = bsxfun(@plus,find(~M),(0:(size(D,3)-1)).*numel(M));
D_masked(index) = NaN;
Run Code Online (Sandbox Code Playgroud)

  • @Matt:为了完整起见,我添加了另一种避免复制"M"的解决方案.如果在非常大的矩阵"M"中只有几个零值,从内存使用的角度来看,这个新的解决方案可能更合适. (2认同)
  • =)我特别喜欢BSXFUN解决方案的发现线性指数.谢谢你加入. (2认同)