it-swarm.com.de

Finden Sie Indizes von Elementen in einem Array basierend auf einer Suche aus einem anderen Array

Stellen Sie sich vor, ich habe zwei Arrays:

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

b = [5, 9, 6];

Ich möchte die Indizes der Werte von b in a finden (nur der erste Treffer), dh:

c = [3, 6, 5];

Gibt es eine einfache, native Methode von Matlab, ohne Schleifen und Suchen.

Ich habe versucht, find () zu verwenden mit:

find(a == b)

und es würde funktionieren, wenn Sie dies tun würden:

for i = 1:length(b)
    index = find(a == b(i));
    c = [c, index(1)]
end

Aber es wäre ideal, wenn es einfacher wäre als dies. 

26

Dies ist tatsächlich in ismember eingebaut. Sie müssen nur das richtige Flag setzen, dann ist es ein Einzeiler und Sie brauchen keinen Arrayfun. Versionen, die neuer als R2012b sind, verwenden dieses Verhalten standardmäßig.

Ursprünglich würde ismember das letzte Vorkommen zurückgeben, wenn mehrere vorhanden sind. Das Flag R2012a gibt das erste zurück.

Hier sind meine Testergebnisse:

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
17
scenia

Sie können Ihre for-Schleife leicht mit arrayfun zu einem einfachen Einzeiler komprimieren:

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

siehe auch Scenias Antwort für neuere Matlab-Versionen (> R2012b).

20
Gunther Struyf

Dies ist ein Fix für den ismember-Ansatz, den @Pursuit vorschlug. Auf diese Weise werden mehrere Vorkommen einer der Zahlen behandelt und das Ergebnis in der richtigen Reihenfolge zurückgegeben:

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

Das Ergebnis:

>> c
c =
     3     6     5
5
Amro

Sie könnten dies versuchen:

[c,ind_a] = intersect(a,b)
4
twerdster
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

Hinweis: Ich habe am Ende von a einen zusätzlichen 6 hinzugefügt, um zu zeigen, dass nur der erste Wert jedes Wertes gefunden wird.

4
tmpearce

Haben Sie ismember ausprobiert?

c_logical_mask = ismember(a, b);

oder

c_indexes = find(ismember(a, b));
1
Pursuit

Ähnlich wie @ tmpearce's Antwort , aber möglicherweise schneller:

[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
1
Luis Mendo
a = [1, 2, 5, 7, 6, 9, 8, 3, 4, 7, 0];
b = [5, 9, 6];
c = dsearchn(a',b');

Für Matlab müssen a und b Spaltenvektoren sein, daher die Transponierte.

1
glarson