2014-08-27 81 views
1

给定2x3矩阵x和4x2矩阵y,我想使用y的每一行来索引到x。如果x中的值不等于-1我想从y中删除该行。下面是一个我喜欢的例子,除了我想以快速,简单的方式完成而没有循环。根据第二个矩阵中的值过滤矩阵行

x = [1, 2, 3; -1, 2, -1]; 
y = [1, 1; 1, 3; 2, 1; 2, 3]; 

for i=size(y,1):-1:1 
    if x(y(i,1), y(i,2)) ~= -1 
     y(i,:) = []; 
    end 
end 

这导致:

y = 

    2  1 
    2  3 

回答

3

原始的方法来sub2ind遵循什么(13759本看起来很漂亮solution由Luis发布)本质上就是这样 -

y = y(x((y(:,2)-1)*size(x,1)+y(:,1))==-1,:) 

标杆

基准测试代码

N = 5000; 
num_runs = 10000; 

x = round(rand(N,N).*2)-1; 
y = zeros(N,2); 
y(:,1) = randi(size(x,1),N,1); 
y(:,2) = randi(size(x,2),N,1); 

disp('----------------- With sub2ind ') 
tic 
for k = 1:num_runs 
    y1 = y(x(sub2ind(size(x), y(:,1), y(:,2)))==-1,:); 
end 
toc,clear y1 

disp('----------- With raw version of sub2ind ') 
tic 
for k = 1:num_runs 
    y2 = y(x((y(:,2)-1)*size(x,1)+y(:,1))==-1,:); 
end 
toc 

结果

----------------- With sub2ind 
Elapsed time is 4.095730 seconds. 
----------- With raw version of sub2ind 
Elapsed time is 2.405532 seconds. 
+0

+1干得好!有一段时间我不知道'sub2ind',我会这样做。然后我发现这个函数并且很懒:-) – 2014-08-27 21:04:25

+0

@LuisMendo哈哈,你怎么不知道'sub2ind'! :)嗯,这很有趣我猜想,当我们想要避免性能函数调用,并依靠基本的数学运算,让我们的大脑移动:)你已经有了我的+1! – Divakar 2014-08-27 21:09:01

+0

一开始我不知道'sub2ind',甚至不知道线性索引。我认为线性索引是一些Matlab的bug! (“Matlab如何允许二维数组使用_one_索引进行索引?”)然后,我得到了它的逻辑并开始使用它,但手动进行转换,就像在你的回答中一样 – 2014-08-27 21:18:28

0
>> x = [1, 2, 3; -1, 2, -1]; 
>>y = [1, 1; 
    1, 2; 
    1, 3; 
    2, 1; 
    2, 2; 
    2, 3]; 
>>row_idx = reshape((x == -1)',1,6); 
>>y = y(row_idx,:); 

我认为你并没有包括在y中的x的所有索引。我把它们都包含在y中。看看..

广义版本:

>> x = [1, 2, 3; -1, 2, -1]; 
>>y = [1, 1; 
    1, 2; 
    1, 3; 
    2, 1; 
    2, 2; 
    2, 3]; 
>>row_idx = reshape((x == -1)',1,size(x,1)*size(x,2)); 
>>y = y(row_idx,:); 
+0

谢谢@lakesh,错过了一些指标是经过深思熟虑的。我应该在提问中提到,对不起。 – sclarke81 2014-08-27 14:48:47

+0

如果您可以制作一个通用版本,我很乐意将其纳入基准测试。 – Divakar 2014-08-27 16:31:02

+0

已编辑代码... – lakesh 2014-08-27 16:38:23

2

这可以很容易矢量如下(见sub2ind):

y = y(x(sub2ind(size(x), y(:,1), y(:,2)))==-1,:);