将 2D 阈值应用于 3D 阵列

Apply 2D threshold to 3D array

对于大小为 20x30 的地理网格,我有两个(温度)变量:

大小为 20x30x100
的数据 A 和一个 threshold 尺寸 20x30

我想将阈值应用于数据,即删除 A 中高于 threshold 的值,每个网格点都有自己的阈值。由于这将为每个网格点提供不同数量的值,我想用零填充其余部分,以便生成的变量,我们称之为 B,大小也将是 20x30x100.

我正想做这样的事情,但是循环有问题:

B = sort(A,3); %// sort third dimension in ascending order
threshold_3d = repmat(threshold,1,1,100); %// make threshold into same size as B

for i=1:20
    for j=1:30
        if B(i,j,:) > threshold_3d(i,j,:); %// if B is above threshold
          B(i,j,:); %// keep values
        else
          B(i,j,:) = 0; %// otherwise set to zero
        end
    end
end

循环的正确方法是什么?
还有什么其他选择可以做到这一点?

感谢您的帮助!

您可以使用 bsxfun 以获得更有效的解决方案,它将在内部处理使用 repmat 完成的复制,就像这样 -

B = bsxfun(@times,B,bsxfun(@gt,B,threshold))

一个更有效的解决方案可能是使用 logical indexingbsxfun(gt 创建的掩码中设置 False 元素,即 True 使用 [ B 中的 =19=] 归零,从而避免使用 bsxfun(@times,对于巨大的多维数组,这可能 有点贵 ,就像这样 -

B(bsxfun(@le,B,threshold)) = 0

Note on efficiency : 作为关系运算,使用 bsxfun 进行矢量化运算将提供内存和 运行 时间效率。此处讨论了内存效率部分 - BSXFUN on memory efficiency with relational operations and the performance numbers have been researched here - Comparing BSXFUN and REPMAT.

样本运行-

 >> B
 B(:,:,1) =
      8     3     9
      2     8     3
 B(:,:,2) =
      4     1     8
      4     5     6
 B(:,:,3) =
      4     8     5
      5     6     5
 >> threshold
 threshold =
      1     3     9
      1     9     1
 >> B(bsxfun(@le,B,threshold)) = 0
 B(:,:,1) =
      8     0     0
      2     0     3
 B(:,:,2) =
      4     0     0
      4     0     6
 B(:,:,3) =
      4     8     0
      5     0     5