在MATLAB中从矩阵中删除元素的最有效/最优雅的方法是什么? [英] What's the most efficient/elegant way to delete elements from a matrix in MATLAB?

查看:245
本文介绍了在MATLAB中从矩阵中删除元素的最有效/最优雅的方法是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想从矩阵中删除几个特定值(如果存在).矩阵中很可能有多个值副本.

I want to delete several specific values from a matrix (if they exist). It is highly probable that there are multiple copies of the values in the matrix.

例如,考虑一个N×2矩阵intersections.如果值[a b][c d]对在该矩阵中作为行存在,我想删除它们.

For example, consider an N-by-2 matrix intersections. If the pairs of values [a b] and [c d] exist as rows in that matrix, I want to delete them.

假设我要在以下矩阵中删除[-2.0 0.5][7 7]之类的行:

Let's say I want to delete rows like [-2.0 0.5] and [7 7] in the following matrix:

intersections =

   -4.0000    0.5000
   -2.0000    0.5000
    2.0000    3.0000
    4.0000    0.5000
   -2.0000    0.5000

因此删除后我得到:

intersections = 

   -4.0000    0.5000
    2.0000    3.0000
    4.0000    0.5000

最有效/最优雅的方法是什么?

What's the most efficient/elegant way to do this?

推荐答案

尝试以下一种方法(其中 A 是您的交集矩阵, B 是要删除的值):

Try this one-liner (where A is your intersection matrix and B is the value to remove):

A = [-4.0 0.5;
     -2.0 0.5;
      2.0 3.0;
      4.0 0.5;
     -2.0 0.5];
B = [-2.0 0.5];
A = A(~all(A == repmat(B,size(A,1),1),2),:);

然后只需对要删除的每个新 B 重复最后一行.

Then just repeat the last line for each new B you want to remove.

...这是另一个选择:

...and here's another option:

A = A((A(:,1) ~= B(1)) | (A(:,2) ~= B(2)),:);

警告:此处的答案最适用于不希望出现小浮点错误(即具有整数值)的情况.如在后续问题,使用"=="和〜="运算符可能会导致不良结果.在这种情况下,应将上述选项修改为使用关系运算符而不是相等运算符.例如,我添加的第二个选项将更改为:

WARNING: The answers here are best used for cases where small floating point errors are not expected (i.e. with integer values). As noted in this follow-up question, using the "==" and "~=" operators can cause unwanted results. In such cases, the above options should be modified to use relational operators instead of equality operators. For example, the second option I added would be changed to:

tolerance = 0.001;   % Or whatever limit you want to set
A = A((abs(A(:,1)-B(1)) > tolerance) | (abs(A(:,2)-B(2)) > tolerance),:);

快站起来! =)

一些基本时间:

如果有人真的对效率感兴趣,我只是对三种不同的方式做了一些简单的计时,以获取矩阵的子索引(我在上面列出的两个选项和Fanfan's STRMATCH选项):

In case anyone was really interested in efficiency, I just did some simple timing for three different ways to get the subindex for the matrix (the two options I've listed above and Fanfan's STRMATCH option):

>> % Timing for option #1 indexing:
>> tic; for i=1:10000, index = ~all(A == repmat(B,size(A,1),1),2); end; toc;
Elapsed time is 0.262648 seconds.
>> % Timing for option #2 indexing:
>> tic; for i=1:10000, index = (A(:,1) ~= B(1)) | (A(:,2) ~= B(2)); end; toc;
Elapsed time is 0.100858 seconds.
>> % Timing for STRMATCH indexing:
>> tic; for i=1:10000, index = strmatch(B,A); end; toc;
Elapsed time is 0.192306 seconds.

如您所见,STRMATCH选项比我的第一个建议要快,但是我的第二个建议是这三个建议中最快的.但是请注意,我的选项和Fanfan的功能稍有不同:我的选项将行的逻辑索引返回到 keep ,而Fanfan的行的线性索引返回到 remove .这就是STRMATCH选项使用以下形式的原因:

As you can see, the STRMATCH option is faster than my first suggestion, but my second suggestion is the fastest of all three. Note however that my options and Fanfan's do slightly different things: my options return logical indices of the rows to keep, and Fanfan's returns linear indices of the rows to remove. That's why the STRMATCH option uses the form:

A(index,:) = [];

我的使用以下格式:

A = A(index,:);

但是,我的索引可以取反,以使用第一种形式(将行索引到删除):

However, my indices can be negated to use the first form (indexing rows to remove):

A(all(A == repmat(B,size(A,1),1),2),:) = [];    % For option #1
A((A(:,1) == B(1)) & (A(:,2) == B(2)),:) = [];  % For option #2

这篇关于在MATLAB中从矩阵中删除元素的最有效/最优雅的方法是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆