2017-09-13 53 views
3

我试图在MATLAB中执行一个行方向的“ismember”,以便找出SetInput的每个元素的位置。 这是我迄今的工作。Row-wise“ismember”without for-loop

function lia = ismemberrow(Input, Set) 
    lia = false(size(Input)); % Pre-assign the output lia 
    for J = 1 : size(Input,1) 
     % The J-th row of "lia" is the list of locations of the 
     % elements of Input(J,:) in Set 
     lia(J,:) = find(ismember(Set, Input(J,:))); 
    end 
end 

例如,如果变量InputSet定义如下

Input = [1 4; 
     4 2; 
     4 3; 
     2 4; 
     1 2; 
     3 2]; 
Set = [3 2 4 1]; 

的输出的lia = ismemberrow(Input,Set)lia将是:

lia = [4 3; 
     3 2; 
     3 1; 
     2 3; 
     4 2; 
     1 2]; 

我的函数的工作准确到目前为止,但是这个函数在我的项目中被多次调用,所以我想如果我可以减少for循环它花费更少的时间。我可以对此有一些看法吗?

回答

4

一个调用ismember(无需环路)会给你的第二个输出参数想要什么:

>> [~, lia] = ismember(Input, Set) 

lia = 

    4  3 
    3  2 
    3  1 
    2  3 
    4  2 
    1  2 
1

如果你输入的正整数,你根本无法使用索引

m(Set)=1:numel(Set); 
result = m(Input) 

如果输入范围很大,可以使用稀疏矩阵:

s = sparse(Set,1,1:numel(Set)); 
result = s(Input) 

结果:

4 3 
    3 2 
    3 1 
    2 3 
    4 2 
    1 2 
1

我会跟ismember走在@gnovice's answer。但是这里有一些替代品,只是为了它的乐趣。

  1. 如果Input值是保证在Set

    [ind, ~] = find(bsxfun(@eq, Set(:), Input(:).')); 
    result = reshape(ind, size(Input)); 
    
  2. 如果他们不能保证:

    [ind, val] = max(bsxfun(@eq, Set(:), permute(Input, [3 1 2]))); 
    result = permute(ind.*val, [2 3 1]);