2014-08-27 91 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,:);