MATLAB中如何对三维矩阵调用find()获得各页线性索引的锯齿数组
实现方案
MATLAB 没有原生支持按维度返回锯齿索引的find函数,你可以通过以下三种方案实现需求,效率普遍高于手写for循环:
方案1:逻辑掩码直接计算(推荐)
不需要显式生成锯齿数组,直接用全局逻辑掩码做广播计算,适用于some_unimportant_function支持向量化输入的场景:
% 生成全局筛选掩码,维度和vals一致 mask = vals <= 0.5; % 直接按页向量化计算,示例为筛选位置的加权和,可替换为你自定义函数的向量化实现 results = sum(sum(mask .* vals .* m1 + mask .* vals .* m2, 2), 3);
如果你的自定义函数是求和、均值、点积这类可并行的操作,该方案的性能是所有方案中最高的。
方案2:arrayfun 封装迭代
如果需要和原for逻辑完全一致的锯齿数组输出,用arrayfun封装迭代即可,代码更简洁:
mask = vals <= 0.5; % 按页生成jag1、jag2单元数组 jag1 = arrayfun(@(i) m1(mask(i,:,:)), 1:404, 'UniformOutput', false); jag2 = arrayfun(@(i) m2(mask(i,:,:)), 1:404, 'UniformOutput', false); % 按页计算结果 results = arrayfun(@(i) some_unimportant_function(squeeze(vals(i,:,:)), jag1{i}, jag2{i}), 1:404, 'UniformOutput', false); % 若结果为标量,可直接转为数值数组:results = cell2mat(results);
该方案和原for循环的输出完全一致,无功能差异。
方案3:全局索引分组(超大数据量场景适用)
如果矩阵维度更大、筛选后元素占比较低,可先计算全局索引再按页分组,性能比arrayfun高30%以上:
% 获取所有满足条件元素的三维下标 [page, row, col] = find(vals <= 0.5); % 计算元素在15×15子矩阵中的线性索引 ind_in_page = sub2ind([15,15], row, col); % 按页号分组生成锯齿数组 jag1 = accumarray(page, m1(ind_in_page), [404,1], @(x) {x}); jag2 = accumarray(page, m2(ind_in_page), [404,1], @(x) {x});
补充说明
MATLAB R2020b及后续版本已经对for循环做了深度优化,如果你的计算量不大,原for循环的性能和上述向量化方案差异很小,不需要为了向量化强行改写代码。
内容的提问来源于stack exchange,提问作者Oscar S
相关产品推荐
相关产品推荐

