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

发布于 2024-09-13 01:35:35 字数 566 浏览 3 评论 0原文

假设我有 D,一个 X×Y×Z 数据矩阵。我还有 M,一个 X×Y“掩蔽”矩阵。我的目标是当 M 中的 (Xi,Yi) 为 false 时,将 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

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

Suppose I have D, an X-by-Y-by-Z data matrix. I also have M, an X-by-Y "masking" matrix. My goal is to set the elements (Xi,Yi,:) in D to NaN when (Xi,Yi) in M is false.

Is there any way to avoid doing this in a loop? I tried using ind2sub, but that fails:

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

I suspect I'm missing something obvious here. (:

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

貪欢 2024-09-20 01:35:35

您可以通过使用 REPMAT,使其与 D 大小相同。然后,索引消失:

D_masked = D;
D_masked(repmat(~M,[1 1 size(D,3)])) = NaN;

如果不希望复制掩码矩阵,还有另一种选择。您可以首先找到 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;

You can do this by replicating your logical mask M across the third dimension using REPMAT so that it is the same size as D. Then, index away:

D_masked = D;
D_masked(repmat(~M,[1 1 size(D,3)])) = NaN;

If replicating the mask matrix is undesirable, there is another alternative. You can first find a set of linear indices for where M equals 0, then replicate that set size(D,3) times, then shift each set of indices by a multiple of numel(M) so it indexes a different part of D in the third dimension. I'll illustrate this here using BSXFUN:

D_masked = D;
index = bsxfun(@plus,find(~M),(0:(size(D,3)-1)).*numel(M));
D_masked(index) = NaN;
内心荒芜 2024-09-20 01:35:35

Reshape基本上是免费的,您可以在这里使用它来获得有效的解决方案。将整体简化为二维问题。

sz=size(D);
D=reshape(D,[],sz(3)); %reshape to 2d
D(isnan(M(:)),:)=nan; %perform the operation on the 2d matrix
D=reshape(D,sz); %reshape back to 3d

Reshape is basically for free, you can use it here for an efficient solution. reducing the whole to a 2d problem.

sz=size(D);
D=reshape(D,[],sz(3)); %reshape to 2d
D(isnan(M(:)),:)=nan; %perform the operation on the 2d matrix
D=reshape(D,sz); %reshape back to 3d
°如果伤别离去 2024-09-20 01:35:35

我的 Matlab 有点生疏,但我认为逻辑索引应该可以工作:(

D_masked = D;
D_masked[ M ] = NaN;

可能可以将其与 rhs 上的条件表达式组合成一个语句......)

My Matlab is a bit rusty but I think logical indexing should work:

D_masked = D;
D_masked[ M ] = NaN;

(which probably can be combined into one statement with a conditional expression on the rhs...)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文