2010-04-14 45 views

回答

79

如果你只是要刪除的零,後面留下非零的,那麼最好的解決辦法是

a(a==0) = []; 

這將刪除零個元素,使用邏輯索引方法MATLAB。當一個向量的索引是一個與向量長度相同的布爾向量時,MATLAB可以使用該布爾結果來索引它。因此,這相當於

a(find(a==0)) = []; 

而且,當你設置一些數組元素[]在MATLAB中,慣例是將它們刪除。

如果你想要把零點到一個新的結果B,同時留下一個不變的,最好的辦法可能是

b = a(a ~= 0); 

同樣,邏輯索引在這裏使用。你也可以使用的

b = a(find(a ~= 0)); 

等效版本(在結果而言),但mlint將結束標記行作爲一個在純粹的邏輯指數更高效,從而更合適。

一如既往,謹防EXACT測試爲零或任何數字,如果您接受的元素在零容許偏差範圍內。做這樣的測試

b = a(abs(a) >= tol); 

這隻會保留那些至少與您的容差一樣大的元素。

+1

或者對於第一個例子,「a = a(a〜= 0)」就足夠了,就地分配工作正常。對一個小數字而不是0測試的好點。 – mtrw 2010-04-14 09:37:54

+0

@woodchips:剛剛發佈了一個性能比較:) – tim 2012-01-23 12:13:58

3
b = a(find(a~=0)) 
+2

只是'b = a(find(a))'就足夠了,默認是找到非零值。 – wich 2010-04-14 08:50:10

+5

或'b = a(a〜= 0)'就足夠了,就暗示了邏輯索引。 – mtrw 2010-04-14 09:07:38

+1

好評,我覺得糟糕的答案upvoted。 – 2010-04-14 09:23:32

8

我只是遇到了這個問題,並希望能找到一些有關的表現,但我做不到,所以我寫了我自己的一個基準測試腳本:,該解決方案使用A = A(A ~= 0)

% Config: 
rows = 1e6; 
runs = 50; 

% Start: 
orig = round(rand(rows, 1)); 

t1 = 0; 
for i = 1:runs 
    A = orig; 
    tic 
    A(A == 0) = []; 
    t1 = t1 + toc; 
end 
t1 = t1/runs; 

t2 = 0; 
for i = 1:runs 
    A = orig; 
    tic 
    A = A(A ~= 0); 
    t2 = t2 + toc; 
end 
t2 = t2/runs; 

t1 
t2 
t1/t2 

所以你看是兩個更快:)

4

我經常最終做這樣的事情。因此我試圖編寫一個簡單的函數,以簡單的方式「剪切」不需要的元素。這將打開MATLAB邏輯有點顛倒,但看起來很不錯:

b = snip(a,'0') 

,你可以找到在函數文件: http://www.mathworks.co.uk/matlabcentral/fileexchange/41941-snip-m-snip-elements-out-of-vectorsmatrices

它還適用於其他所有的「x」,NaN或任何元素。

+6

這是一個強大的錘子,可以讓一隻小小的蒼蠅sm ...作響...... – Shai 2013-06-03 05:00:02

2

爲什麼不只是,a=a(~~a)a(~a)=[]。這相當於其他方法,但肯定不太關鍵。

2

數據

a=[0 3 0 0 7 10 3 0 1 0 7 7 1 7 4] 

aa=nonzeros(a)' 

結果

aa=[3 7 10 3 1 7 7 1 7 4] 
+0

爲什麼不讓這個帖子更好:添加一個鏈接到文檔和使用適當的突出顯示爲您的代碼 – Sjon 2015-09-16 09:02:40

+0

我認爲這是一個很好的答案!與其他提案進行比較將會很好。 – 2016-03-05 18:00:18

2

你可以使用稀疏(一),這將返回

(1,2)1

(1,4)3

這可以讓您保留有關您的非零條目的位置的信息。