2017-09-13 52 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]);