繁体   English   中英

找到矩阵的第一个非零列(矢量化版本)

[英]Find the first non-zero column of a matrix (vectorized edition)

我问自己,找到矩阵的第一个非零列的值的最“矢量化”解决方案是什么样的。 如果存在矢量化解决方案但非常丑陋/ hackish,我也要求最优雅的解决方案。

假设我们有一个矩阵M ,我们可以假设它包含至少一个非零值:

 M =
     0     0     1     0     0
     0     0     2     0     0
     0     0     3     0     42
     0     0     4     0     0
     0     0     0     0     0

我想在第一列中找到不是全零的值; 所以对于这个例子,期望的输出将是:

 column = 
    1
    2
    3
    4
    0

我的第一次尝试使用for循环并且工作正常,但它可能没有充分利用matlab中提供的工具。

>> for i = 1:size(M,2)
    col = M(:,i);
    if find(col) % empty array evaluates to false
        break;
    end
end
>> col
col =
     1
     2
     3
     4
     0

我想出的另一个解决方案是使用嵌套的findcellfun调用,但它可能仍然不是解决问题的最佳方法。

>> C = find(cellfun(@isempty, cellfun(@find, num2cell(M,1), 'UniformOutput', 0)) == 0)
C =
     3     5
>> M(:,C(1))
ans =
     1
     2
     3
     4
     0

这是一种方法,我会留给你测量它的性能改进(如果你感兴趣的话) -

M(:,find(any(M),1))

我建议Logical Operation in MATLABlogical indexing ,因为它们在索引方面非常方便。 这些应该很好。

当您要求“矢量化”解决方案时,由于逻辑索引,这个解决方案应该运行得更快一些:

tic; M(:,sum(M)>0); toc
Elapsed time is 0.000020 seconds.

tic; M(:,find(any(M),1)); toc
Elapsed time is 0.000028 seconds.

(虽然这不是衡量执行时间的最准确方法)

编辑:

更准确的方法是在更大的矩阵上测量timeit

M=rand(1024); 
f1= @() M(:,sum(M)>0);
f2= @() M(:,find(any(M),1)); 
t1=timeit(f1)
t2=timeit(f2)

t1 =
    0.0070
t2 =
   2.3288e-05

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM