私は2つの配列を持っていると想像してください:
a = [1, 2, 5, 7, 6, 9, 8, 3, 4, 7, 0];
b = [5, 9, 6];
私はa(最初のヒットのみ)のbの値のインデックスを見つけたい:
c = [3, 6, 5];
ループや検索をせずにこれを行う簡単なMatlabネイティブの方法はありますか。
私はfind()を以下で使用しようとしました:
find(a == b)
これを行うと動作します:
for i = 1:length(b)
index = find(a == b(i));
c = [c, index(1)]
end
しかし、これよりも簡単であることが理想です。
Arrayfunを使用してforループを簡単に圧縮して、簡単な1行にまとめることができます。
arrayfun(@(x) find(a == x,1,'first'), b )
新しいMatlabバージョン(> R2012b)については Sceniaの答え も参照してください。
これは、 @ Pursuit が提案したismember
アプローチの修正です。この方法では、1つの数字の複数の出現を処理し、正しい順序で結果を返します。
[tf,loc] = ismember(a,b);
tf = find(tf);
[~,idx] = unique(loc(tf), 'first');
c = tf(idx);
結果:
>> c
c =
3 6 5
これを試すことができます:
[c,ind_a] = intersect(a,b)
a = [1, 2, 5, 7, 6, 9, 8, 3, 4, 7, 0, 6];
b = [5, 9, 6];
[r c]=find(bsxfun(@eq,a,b')');
[~,ia,~]=unique(c,'first');
>> r(ia)
ans =
3
6
5
注:追加の6
a
の最後に、各値の最初の出現のみを見つけることを示します。
ismember
を試しましたか?
c_logical_mask = ismember(a, b);
または
c_indexes = find(ismember(a, b));
@ tmpearce's answer に似ていますが、おそらくより高速です:
[valid, result] = max(bsxfun(@eq, a(:), b(:).')); %'// max finds first occurrence
result = result(valid); %// this is necessary in case some value of b is not in a
a = [1, 2, 5, 7, 6, 9, 8, 3, 4, 7, 0];
b = [5, 9, 6];
c = dsearchn(a',b');
Matlabでは、aとbが列ベクトルである必要があるため、転置が必要です。