Filter matrix rows depending on values in a second matrix

后端 未结 3 1887
旧巷少年郎
旧巷少年郎 2020-12-04 03:38

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 i

相关标签:
3条回答
  • 2020-12-04 04:19
    >> 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,:);
    
    0 讨论(0)
  • 2020-12-04 04:23

    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.
    
    0 讨论(0)
  • 2020-12-04 04:32

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

    y = y(x(sub2ind(size(x), y(:,1), y(:,2)))==-1,:);
    
    0 讨论(0)
提交回复
热议问题