sclarke81
sclarke81

Reputation: 1769

Filter matrix rows depending on values in a second matrix

Given a 2x3 matrix x and a 4x2 matrix y, I'd like to use each row of y to index into x. If the value in x is not equal to -1 I'd like to remove that row from y. Here's an example that does what I'd like, except I'd like to do it in a fast, simple way without a loop.

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

This results in:

y =

     2     1
     2     3

Upvotes: 1

Views: 216

Answers (3)

lakshmen
lakshmen

Reputation: 29064

>> 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,:);

I think you didn't include all the index of x in y. I included all of them in y. Have a look..

Generalized version:

>> 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,:);

Upvotes: 0

Divakar
Divakar

Reputation: 221534

A raw approach to what sub2ind follows (as used by this pretty nice-looking solution posted by Luis) inherently would be this -

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

Benchmarking

Benchmarking Code

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

Results

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

Upvotes: 3

Luis Mendo
Luis Mendo

Reputation: 112659

This can be easily vectorized as follows (see sub2ind):

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

Upvotes: 2

Related Questions