2010-04-14 46 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

这可以让您保留有关您的非零条目的位置的信息。