Performance 如何删除矩阵A中与矩阵B在Matlab中指定列中的值相等的行?
我在MatlabA和B中有两个矩阵,它们的列数相等,但行数不同。B中的行数也小于A中的行数。B实际上是A的子集 当A的第1列和第2列中的值等于矩阵B的第1列和第2列中的值时,如何有效地从A中删除这些行 目前我正在这样做:Performance 如何删除矩阵A中与矩阵B在Matlab中指定列中的值相等的行?,performance,matlab,matrix,vectorization,bsxfun,Performance,Matlab,Matrix,Vectorization,Bsxfun,我在MatlabA和B中有两个矩阵,它们的列数相等,但行数不同。B中的行数也小于A中的行数。B实际上是A的子集 当A的第1列和第2列中的值等于矩阵B的第1列和第2列中的值时,如何有效地从A中删除这些行 目前我正在这样做: for k = 1:size(B, 1) A(find((A(:,1) == B(k,1) & A(:,2) == B(k,2))), :) = []; end Matlab抱怨这是低效的,我应该尝试使用any,但我不确定如何使用any。有人能帮我解决这个问
for k = 1:size(B, 1)
A(find((A(:,1) == B(k,1) & A(:,2) == B(k,2))), :) = [];
end
Matlab抱怨这是低效的,我应该尝试使用any
,但我不确定如何使用any
。有人能帮我解决这个问题吗?=)
我试过这个,但不起作用:
A(any(A(:,1) == B(:,1) & A(:,2) == B(:,2), 2), :) = [];
它抱怨如下:
Error using ==
Matrix dimensions must agree.
我想要的示例:
结果中的A-B表示B行从A中删除。A-C也是如此。尝试使用。例如:
c=setdiff(a,b,'rows')
注意,如果订单很重要,请使用:
c = setdiff(a,b,'rows','stable')
Edit:阅读编辑后的问题和对此答案的评论,您要查找的setdiff
的具体用法是(正如Shai所注意到的):
替代解决方案:
您只需使用:
使用:
解释代码:
首先,我们使用bsxfun
比较A
和B
列的所有对First-to-column,结果是compare
大小numRowsA
-by-numRowsB
-by-2和true
其中比较(ii,jj,kk)=A(ii,kk)=B(jj,kk)
然后我们使用
all
创建大小为numRowsA
-by-numRowsB
的twoEq
,其中每个条目表示A
和B
的对应条目是否相等。最后,我们使用
any
选择与至少一行B
匹配的A
行
原始代码有什么问题:
通过删除循环中的A
行(即A(…)=[]
),实际上可以在几乎每次迭代中调整A
。请参见为什么这是一种不良做法
使用
为了仅在前两列上使用setdiff
(如所建议),您需要使用它的第二个输出参数:
[ignore, ia] = setdiff( A(:,1:2), B(:,1:2), 'rows', 'stable' );
A = A( ia, : ); % keeping only relevant rows, beyond first two columns.
下面是另一个
bsxfun
实现-
A(~any(squeeze(all(bsxfun(@eq,A(:,1:2),permute(B(:,1:2),[3 2 1])),2)),2),:)
另一个非常接近,但仍然避免两个排列
到一个排列
-
A(~any(all(bsxfun(@eq,A(:,1:2),permute(B(:,1:2),[3 2 1])),2),3),:)
感谢你的努力你的答案很好
setdiff
是最好的解决方案,但要将您的第一次尝试转换为any
(保持循环),这就是Matlab的建议(在您的情况下,您实际上希望all
,而不是any
):A(all(A==B(k,2),:)=[]代码>顺便说一句,我没有意识到你只是在比较前两列,所以请将我最后的评论更新为A(all(A(:,1:2)==B(k,1:2),2),:)=[]代码>谢谢大家的回答=)最初的运行时间(加上我的数据)是:0.198072秒。通过使用bsxfun
方法,我获得了大约0.007秒的运行时间。通过使用setdiff(A(:,1:2),B(:,1:2),'rows')
我得到了运行时间:0.004120秒。@jjepsoumi希望你也能在更大的数据量上做一些基准测试,看到这些结果也会很有趣。+1@Divakar我将尝试使用不同的数据集并发布我的结果=)这需要几分钟=)+1,但你不需要setdiff(A)吗(:,1:2),B(:,1:2),‘行’
取而代之的是?当我写我的答案时,问题中有一个例子,两个数组与答案中的数组相似,现在被编辑掉了。我总是这样写:“例如,…”如果你理解了答案,你还是可以把它应用到这个问题上。@JJEPSUMI可以在编辑之前把你在帖子中的截图发回来吗?从所有的混乱中,我想到了一个替代的解决方案,ismember
…:)@natan haha避免混乱的方法!+1之外:)@natan哈哈谢谢,这里也是:)
[ignore, ia] = setdiff( A(:,1:2), B(:,1:2), 'rows', 'stable' );
A = A( ia, : ); % keeping only relevant rows, beyond first two columns.
A(~any(squeeze(all(bsxfun(@eq,A(:,1:2),permute(B(:,1:2),[3 2 1])),2)),2),:)
A(~any(all(bsxfun(@eq,A(:,1:2),permute(B(:,1:2),[3 2 1])),2),3),:)