2017-10-21 1 views
2

Gegeben seien zwei Listen:in einem anderen Array A

In [518]: A 
Out[518]: [3, 4, 2, 1, 7, 6, 5] 

In [519]: B 
Out[519]: [4, 6] 

Jedes Element in B existiert in A, ohne Ausnahme.

Ich möchte ein Array von Indizes für B abrufen, wie in A zu sehen. Zum Beispiel ist 4 in Index 1 in A vorhanden, und 6 ist in Position 5 für B. Meine erwartete Ausgabe ist [1, 5] für dieses Szenario.

Dies ist, was ich den Index bekommen haben:

In [520]: np.flatnonzero(np.in1d(a, b)) 
Out[520]: array([1, 5]) 

Leider, dies wird in den meisten anderen Fällen nicht. Beispiel: Wenn B = [6, 4], gibt meine Methode weiterhin [1, 5] aus, wenn sie [5, 1] ausgeben soll.

Gibt es einen effizienten, anzahlreichen Weg, um das zu erreichen, was ich erreichen möchte?

+1

Ziemlich sicher, dass dies vor gekommen ist: Sie können in O((m+n)log(m+n)) durch vorsichtiges Art in1d Ausgang (mit eindeutigen Werten hier) bleiben? Was ist mit Duplikaten? –

+0

Die Hilfe für 'np.where' gibt dieses genaue Beispiel:' ix = np.in1d ​​(A.ravel(), B) .reshape (A.shape); np.where (ix) '. Entschuldigung, stimmt nicht mit Ihrem zweiten Kriterium überein. –

+0

@JonClements Könnte nichts finden ... Was Betrüger in B betrifft, so sollte sicherlich jede Methode, die es wert ist, diese angemessen behandeln, aber es würde mir auch nicht schaden. –

Antwort

2

IIUC entfernt werden kann:

In [71]: a 
Out[71]: array([3, 4, 2, 1, 7, 6, 5, 6, 4]) 

In [72]: b 
Out[72]: array([4, 6]) 

In [73]: np.where(a==b[:,None])[1] 
Out[73]: array([1, 8, 5, 7], dtype=int64) 

In [74]: b = np.array([6, 4]) 

In [75]: np.where(a==b[:,None])[1] 
Out[75]: array([5, 7, 1, 8], dtype=int64) 

UPDATE: wenn Sie brauchen nur Indizes von ersten Vorkommen (falls es Duplikate in A Array), verwenden dann this solution from @Divakar, die schneller sein:

In [84]: (a==b[:,None]).argmax(1) 
Out[84]: array([5, 1], dtype=int64) 
+0

Danke für Ihre Antwort! Ich suche zuerst '[1, 5]' und '[5, 1]' in der zweiten Instanz. Deine Antwort scheint dahin zu kommen, aber nicht ganz da :-) –

+0

@ cᴏʟᴅsᴘᴇᴇᴅ, ich habe dein 'a' Array geändert ;-) – MaxU

+0

Oh mein Gott, ich habe es nicht bemerkt. Ja, genau das suche ich! Vielen Dank! –

0

Ich weiß nicht, ob es effizienter ist, aber

[int(np.isin(A, B[x]).nonzero()[0]) for x in range(len(B))] 

scheint die Rechnung zu passen. Wenn Einzigartigkeit nicht garantiert wird dann die int() Teil

+0

Ehrlich gesagt, dachte ich selbst daran, aber ich wollte etwas weniger ... schleppend. –

0

Wenn m=A.size und n=B.size die where Ansatz ist O(mn).

A= np.unique(np.random.randint(0,100000,100000)) 
np.random.shuffle(A) 
B=np.unique(np.random.randint(0,10000,10000)) 
np.random.shuffle(B) 

def find(A,B): 
    pos=np.in1d(A,B).nonzero()[0] 
    return pos[A[pos].argsort()][B.argsort().argsort()] 

In [5]: np.allclose(np.where(np.equal.outer(B,A))[1],find(A,B)) 
Out[5]: True 

In [6]: %time np.where(np.equal.outer(B,A))[1] 
Wall time: 3.98 s 
Out[6]: array([88220, 13472, 12482, ..., 9795, 39524, 5727], dtype=int64) 

In [7]: %timeit find(A,B) 
22.6 ms ± 366 µs per loop (mean ± std. dev. of 7 runs, 10 loops each) 
Verwandte Themen