如何有效地从(非稀疏)矩阵中删除零?

11 arrays performance matlab matrix matrix-indexing

我有一个矩阵:

x = [0 0 0 1 1 0 5 0 7 0];
Run Code Online (Sandbox Code Playgroud)

我需要删除所有的零,如下所示:

x = [1 1 5 7];
Run Code Online (Sandbox Code Playgroud)

我使用的矩阵很大(1x15000),我需要多次(5000+),所以效率是关键!

gno*_*ice 16

单程:

x(x == 0) = [];
Run Code Online (Sandbox Code Playgroud)

关于时间的说明:

正如木片所提到的,与KitsuneYMG使用的方法相比,这种方法似乎很慢.Loren在她的一篇MathWorks博客文章中也注意到了这一点.既然你提到必须这样做几千次,你可能会注意到一个区别,在这种情况下我会x = x(x~=0);先尝试.

警告:请注意是否使用非整数.例如,如果您想要考虑的非常小的数字足够接近零以便将其删除,则上述代码不会将其删除.只删除精确的零.以下内容将帮助您将"足够接近"的数字删除为零:

tolerance = 0.0001;  % Choose a threshold for "close enough to zero"
x(abs(x) <= tolerance) = [];
Run Code Online (Sandbox Code Playgroud)


Kit*_*YMG 11

只是为了与众不同:

x=x(x~=0);
Run Code Online (Sandbox Code Playgroud)

要么

x=x(abs(x)>threshold);
Run Code Online (Sandbox Code Playgroud)

这也是处理复杂数字的好处


小智 11

这是三种常见的解决方案.它有助于看到差异.

x = round(rand(1,15000));

y = x;

tic,y(y==0) = [];toc

Elapsed time is 0.004398 seconds.

y = x;

tic,y = y(y~=0);toc

Elapsed time is 0.001759 seconds.

y = x;

tic,y = y(find(y));toc

Elapsed time is 0.003579 seconds.
Run Code Online (Sandbox Code Playgroud)

正如您应该看到的,最便宜的方式是直接逻辑索引,选择要保留的元素.查找更昂贵,因为matlab找到这些元素,返回它们的列表,然后索引到向量中.