26

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

しかし、これよりも簡単であることが理想的です。

4

8 に答える 8

20

arrayfun を使用して for ループを単純なワンライナーに簡単に圧縮できます。

arrayfun(@(x) find(a == x,1,'first'), b )

新しい matlab バージョン (>R2012b)については、 Scenia の回答も参照してください。

于 2012-07-20T06:59:11.693 に答える
18

これは実際には に組み込まれてismemberいます。正しいフラグを設定するだけで、それはワンライナーであり、arrayfun は必要ありません。R2012b より新しいバージョンでは、既定でこの動作が使用されます。

元々、ismember複数ある場合は最後のオカレンスを返しますが、R2012a フラグにより​​最初のオカレンスが返されます。

ここに私のテスト結果があります:

a = [1, 2, 5, 7, 6, 9, 8, 3, 4, 7, 0, 6];
b = [5, 9, 6];

[~,c] = ismember(b,a,'R2012a');
>> c
c =
     3     6     5
于 2014-01-24T15:43:58.677 に答える
5

これは、@Pursuitが提案したismemberアプローチの修正です。このようにして、数字の 1 つの複数回の発生を処理し、正しい順序で結果を返します。

[tf,loc] = ismember(a,b);
tf = find(tf);
[~,idx] = unique(loc(tf), 'first');
c = tf(idx);

結果:

>> c
c =
     3     6     5
于 2012-07-20T13:36:17.157 に答える
4
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

于 2012-07-20T03:12:32.820 に答える
1
a = [1, 2, 5, 7, 6, 9, 8, 3, 4, 7, 0];
b = [5, 9, 6];
c = dsearchn(a',b');

Matlab では a と b が列ベクトルである必要があるため、転置が必要です。

于 2013-08-01T15:24:04.030 に答える
1

試しましたismemberか?

c_logical_mask = ismember(a, b);

また

c_indexes = find(ismember(a, b));
于 2012-07-20T03:38:44.167 に答える
1

@tmpearceの回答に似ていますが、おそらくより高速です:

[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
于 2014-06-24T10:20:11.627 に答える