2016-05-26 8 views
5

Ich habe ein Array/set mit einzigartigen positiven ganzen Zahlen, dhNumpy Auffinden Elementindex in einem anderen Array

>>> unique = np.unique(np.random.choice(100, 4, replace=False)) 

und ein Array abgetastete mehr Elemente aus dieser früheren Anordnung enthält, wie

>>> A = np.random.choice(unique, 100) 

Ich möchte die Werte des Arrays A auf die Position abbilden, in der diese Werte in unique auftreten.

Bisher ist die beste Lösung, die ich ist durch ein Mapping-Array gefunden:

>>> table = np.zeros(unique.max()+1, unique.dtype) 
>>> table[unique] = np.arange(unique.size) 

Die oben weist jedes Element des Index auf dem Array und damit später verwendet werden, um abbilden A durch Indexierung:

>>> table[A] 
array([2, 2, 3, 3, 3, 3, 1, 1, 1, 0, 2, 0, 1, 0, 2, 1, 0, 0, 2, 3, 0, 0, 0, 
     0, 3, 3, 2, 1, 0, 0, 0, 2, 1, 0, 3, 0, 1, 3, 0, 1, 2, 3, 3, 3, 3, 1, 
     3, 0, 1, 2, 0, 0, 2, 3, 1, 0, 3, 2, 3, 3, 3, 1, 1, 2, 0, 0, 2, 0, 2, 
     3, 1, 1, 3, 3, 2, 1, 2, 0, 2, 1, 0, 1, 2, 0, 2, 0, 1, 3, 0, 2, 0, 1, 
     3, 2, 2, 1, 3, 0, 3, 3], dtype=int32) 

Welche bereits gibt mir die richtige Lösung. Wenn die eindeutigen Zahlen in unique jedoch sehr spärlich und groß sind, bedeutet dies, dass ein sehr großes table Array erstellt wird, um nur einige Zahlen für die spätere Zuordnung zu speichern.

Gibt es eine bessere Lösung?

HINWEIS: Sowohl A als auch unique sind Beispiel-Arrays, nicht echte Arrays. So ist die Frage nicht, wie ist Positions Indizes zu erzeugen, ist es einfach, wie effizient Elemente A zu Indizes in unique Karte zu, den Pseudo-Code das, was ich in numpy Speedup möchte wie folgt ist,

B = np.zeros_like(A) 
for i in range(A.size): 
    B[i] = unique.index(A[i]) 

(unter der Annahme unique ist eine Liste in der obigen Pseudocode).

Antwort

4

Die Tabelle Ansatz in Ihrer Frage beschrieben, ist die beste Option, wenn unique wenn ziemlich dicht, aber unique.searchsorted(A) sollte das gleiche Ergebnis produzieren und erfordert keine unique zu sei dicht. searchsorted ist großartig mit Ints, wenn jemand versucht, diese Art von Ding mit Floats, die Präzision Einschränkungen haben, etwas wie this.

+0

Und 'Sortierer' könnte damit verwendet werden, wenn' unique' nicht bereits sortiert ist. – Divakar

1

können Sie Standard-Python verwenden dict mit np.vectorize

inds = {e:i for i, e in enumerate(unique)} 
B = np.vectorize(inds.get)(A) 
+0

Interessanter Ansatz, ich werde die Leistung von 'np.vectorize' für große Matrizen testen müssen. –

+0

np.vectorize Schleifen auf der Python-Ebene, also keine Notwendigkeit, diesen Test durchzuführen ... es ist nur syntaktischer Zucker –

2

Das numpy_indexed Paket (Disclaimer: Ich bin sein Autor) enthält einen äquivalent von vektorisierten list.index, die Speicher erfordern nicht proportional zu dem max-Elemente, aber nur proportional zum Eingang selbst:

import numpy_indexed as npi 
npi.indices(unique, A) 

Beachten Sie, dass dies auch für beliebige Dtypes und Dimensionen funktioniert. Außerdem muss das abgefragte Array nicht eindeutig sein. Der erste gefundene Index wird zurückgegeben, derselbe wie für die Liste.

Verwandte Themen