[英]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
我想出的另一個解決方案是使用嵌套的find
和cellfun
調用,但它可能仍然不是解決問題的最佳方法。
>> 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 MATLAB
和logical 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.