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

发布于 2024-07-16 07:14:37 字数 184 浏览 5 评论 0原文

我有一个矩阵:

x = [0 0 0 1 1 0 5 0 7 0];

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

x = [1 1 5 7];

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

I have a matrix:

x = [0 0 0 1 1 0 5 0 7 0];

I need to remove all of the zeroes, like so:

x = [1 1 5 7];

The matrices I am using are large (1x15000) and I need to do this multiple times (5000+), so efficiency is key!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

预谋 2024-07-23 07:14:37

一种方法:

x(x == 0) = [];

关于时间的说明:

正如木片,与 狐YMG。 Loren 在她的一篇 MathWorks 博客文章。 由于您提到必须执行此操作数千次,因此您可能会注意到差异,在这种情况下,我会首先尝试 x = x(x~=0);

警告:如果您使用非整数,请小心。 例如,如果您有一个非常小的数字,您希望将其视为足够接近零以便将其删除,则上述代码将不会删除它。 仅删除精确的零。 以下内容还将帮助您删除“足够接近”零的数字:

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

One way:

x(x == 0) = [];

A note on timing:

As mentioned by woodchips, this method seems slow compared to the one used by KitsuneYMG. This has also been noted by Loren in one of her MathWorks blog posts. Since you mentioned having to do this thousands of times, you may notice a difference, in which case I would try x = x(x~=0); first.

WARNING: Beware if you are using non-integer numbers. If, for example, you have a very small number that you would like to consider close enough to zero so that it will be removed, the above code won't remove it. Only exact zeroes are removed. The following will help you also remove numbers "close enough" to zero:

tolerance = 0.0001;  % Choose a threshold for "close enough to zero"
x(abs(x) <= tolerance) = [];
一花一树开 2024-07-23 07:14:37

只是为了与众不同:

x=x(x~=0);

或者

x=x(abs(x)>threshold);

这也有处理复数的好处

Just to be different:

x=x(x~=0);

or

x=x(abs(x)>threshold);

This has the bonus of working on complex numbers too

我乃一代侩神 2024-07-23 07:14:37

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

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.

正如您所看到的,最便宜的方法是直接逻辑索引,选择要保留的元素。 查找的成本更高,因为 matlab 查找这些元素,返回它们的列表,然后索引到向量中。

Those are the three common solutions. It helps to see the difference.

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.

As you should see, the cheapest way is the direct logical index, selecting out the elements to be retained. The find is more expensive, since matlab finds those elements, returning a list of them, and then indexes into the vector.

傲影 2024-07-23 07:14:37

这是另一种方法

y = x(find(x))

我将让您来计算您尝试的各种方法的相对效率 - 请写下来并让我们都知道。

Here's another way

y = x(find(x))

I'll leave it to you to figure out the relative efficiency of the various approaches you try -- do write and let us all know.

请持续率性 2024-07-23 07:14:37

虽然我的计时结果并不能确定它是否明显更快,但这似乎是最快和最简单的方法:

y = nonzeros(y) 

Though my timing results are not conclusive to whether it is significantly faster, this seems to be the fastest and easiest approach:

y = nonzeros(y) 
花心好男孩 2024-07-23 07:14:37
x = [0 0 0 1 1 0 5 0 7 0]
y = [0 2 0 1 1 2 5 2 7 0]

然后 x2 和 y2 可以通过以下方式获得:

x2=x(~(x==0 & y==0))
y2=y(~(x==0 & y==0))

x2 = [0     1     1     0     5     0     7]
y2 = [2     1     1     2     5     2     7]

希望这有帮助!

x = [0 0 0 1 1 0 5 0 7 0]
y = [0 2 0 1 1 2 5 2 7 0]

Then x2 and y2 can be obtained as:

x2=x(~(x==0 & y==0))
y2=y(~(x==0 & y==0))

x2 = [0     1     1     0     5     0     7]
y2 = [2     1     1     2     5     2     7]

Hope this helps!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文