Matlab原生方式消除x y点

时间:2012-06-29 05:08:53

标签: matlab

所以我有一组两个x,y,z点列表。

List1 and List2.

我想删除List2中存在的所有点,这些点也存在于List2中。在此示例中,List2中的大多数点(可能是100%)将存在于List1中。例如:

的List1

1, 2, 3
4, 5, 6
7, 8, 9

列表2

7, 8, 9

输出

1, 2, 3
4, 5, 6

这将发生在每个列表大小的数千个点上。显然,这可以通过循环List2和搜索时间为O(n * m)的列表1来完成。是否有更快,更matlab的本地方式来做到这一点?

感谢您的帮助。

3 个答案:

答案 0 :(得分:4)

尝试:SETDIFF(List1, List2, 'rows')

(我不知道它有多高效,但由于它是一种原生方法,它可能已经过优化。)

答案 1 :(得分:2)

@Turix的setdiff选项应该有效。另一种选择(仅适用于踢球)是

List1(~ismember(List1,List2,'rows'), :);

答案 2 :(得分:2)

我发现这样做的速度略快(尽管不那么普遍)。当我学习格式化时,第一个答案就是忍受我...

我发现没有值得注意的缩放效果,因此我将使用以下Lists对象作为示例:

example_step=3;
max_value_outer=example_step*333;
max_value_inner=example_step*33;
List1=[1:example_step:max_value_outer; 2:example_step:max_value_outer; 3:example_step:max_value_outer]';
List2=[1:example_step:max_value_inner; 2:example_step:max_value_inner; 3:example_step:max_value_inner]';

到目前为止,Turix的内置setdiff调用提供了最佳结果,在不到3秒的时间内运行以下代码块:

tic; 
  for i=1:10000 result=setdiff(list1,list2,'rows'); 
  end;
toc
>> Elapsed time is 2.821303 seconds.

但是,如果您的示例数据集代表了您的数据是向量,整数以及在合理限制范围内的事实,那么您可以通过使用sub2ind比较线性索引等效而不是三元组来加快速度,就像这样:

range=max_value_outer*ones(1,3);
[c,ia] = setdiff(sub2ind(range,List1(:,1),List1(:,2),List1(:,3)), sub2ind(range,List2(:,1),List2(:,2),List2(:,3))); result=List1(ia,:);
  result=List1(ia,:); 

如果运行10,000次以与行直接setdiff进行比较,则可以获得此

tic;
for i=1:10000 
  range=max_value_outer*ones(1,3); 
  [c,ia] = setdiff(sub2ind(range,List1(:,1),List1(:,2),List1(:,3)), sub2ind(range,List2(:,1),List2(:,2),List2(:,3))); 
  result=List1(ia,:); 
end; 
toc
>> Elapsed time is 2.285992 seconds.

因此,来自setdiff(,,'行)的执行时间约为20左右,而来自for循环实现(未示出)的执行时间约为98%。根据您的数据的确切含义,我可以想到一些可能会进一步加快速度的想法。例如,如果您考虑的maximum_value与内存相比相对较小,则可以通过将样本空间映射到内存上来利用线性索引,然后使用List1设置位高的线性索引,然后使用List2中的集合来设置他们很低。任何保持高位的位都在List1上,而不是List2。有here的简化版本,但我不担保该实现。

希望有所帮助!