Wie wähle man den Wert aus dem Array aus, das dem Wert im Array mit der Vektorisierung am nächsten liegt?

Ich habe eine Reihe von Werten, die ich durch eine Reihe von Entscheidungen ersetzen möchte, basierend darauf, welche Wahl linear am nächsten ist.

Der Fang ist die Größe der Entscheidungen zur Laufzeit definiert.

import numpy as np a = np.array([[0, 0, 0], [4, 4, 4], [9, 9, 9]]) choices = np.array([1, 5, 10]) 

Wenn Entscheidungen statisch waren, würde ich einfach np.wo benutzen

 d = np.where(np.abs(a - choices[0]) > np.abs(a - choices[1]), np.where(np.abs(a - choices[0]) > np.abs(a - choices[2]), choices[0], choices[2]), np.where(np.abs(a - choices[1]) > np.abs(a - choices[2]), choices[1], choices[2])) 

Um die Ausgabe zu erhalten:

 >>d >>[[1, 1, 1], [5, 5, 5], [10, 10, 10]] 

Gibt es einen Weg, dies zu tun dynamischer, während immer noch die Vektorisierung.

  • Verwirrung über Numpy's gelten auf der Achse und Listenverständnisse
  • Effiziente, einheitliche Funktionsberechnung in Python
  • Wie man 3D Numpy Arrays vektorisiert
  • Vektorisierte Backtest-Erstellung von Pandas DataFrame
  • Vergleich des einzelnen Dataframe-Wertes mit vorherigen 10 in derselben Spalte
  • Berechnen der Anzahl spezifischer aufeinander folgender gleicher Werte in vektorisierter Weise in Pandas
  • Machen Sie ein numpy Array monoton ohne Python Loop
  • Wie man eine einfache für Schleife in Python / Numpy vektorisiert
  • 3 Solutions collect form web for “Wie wähle man den Wert aus dem Array aus, das dem Wert im Array mit der Vektorisierung am nächsten liegt?”

    Subtrahieren Sie die Auswahl von a , finden Sie den Index des Minimums des Ergebnisses, ersetzen Sie.

     a = np.array([[0, 0, 0], [4, 4, 4], [9, 9, 9]]) choices = np.array([1, 5, 10]) b = a[:,:,None] - choices np.absolute(b,b) i = np.argmin(b, axis = -1) a = choices[i] print a >>> [[ 1 1 1] [ 5 5 5] [10 10 10]] a = np.array([[0, 3, 0], [4, 8, 4], [9, 1, 9]]) choices = np.array([1, 5, 10]) b = a[:,:,None] - choices np.absolute(b,b) i = np.argmin(b, axis = -1) a = choices[i] print a >>> [[ 1 1 1] [ 5 10 5] [10 1 10]] >>> 

    Die zusätzliche Dimension wurde zu a addiert, so dass jedes Element der choices von jedem Element von a subtrahiert würde. choices wurden gegen a in der dritten Dimension ausgestrahlt. Dieser Link hat eine anständige Grafik . b.shape ist (3,3,3). EricsBroadcastingDoc ist eine ziemlich gute Erklärung und hat ein grafisches 3-d Beispiel am Ende.

    Für das zweite Beispiel:

     >>> print b [[[ 1 5 10] [ 2 2 7] [ 1 5 10]] [[ 3 1 6] [ 7 3 2] [ 3 1 6]] [[ 8 4 1] [ 0 4 9] [ 8 4 1]]] >>> print i [[0 0 0] [1 2 1] [2 0 2]] >>> 

    Die endgültige Zuweisung verwendet eine Index-Array- oder Integer-Array-Indexierung .

    Im zweiten Beispiel bemerken, dass es eine Bindung für Element a[0,1] , entweder eins oder fünf könnte ersetzt worden sein.

    Um die exzellente Antwort von wwii etwas näher zu erklären:

    Die Idee ist, eine neue Dimension zu schaffen, die den Job des Vergleichens jedes Elementes von a zu jedem Element in choices mit numpy Broadcasting macht . Dies geschieht leicht für eine beliebige Anzahl von Dimensionen in a Verwendung der Ellipse-Syntax :

     >>> b = np.abs(a[..., np.newaxis] - choices) array([[[ 1, 5, 10], [ 1, 5, 10], [ 1, 5, 10]], [[ 3, 1, 6], [ 3, 1, 6], [ 3, 1, 6]], [[ 8, 4, 1], [ 8, 4, 1], [ 8, 4, 1]]]) 

    Wenn argmin auf die gerade angelegte Achse gehst (die letzte Achse mit Etikett -1) gibt dir den gewünschten Index in der choices , die du ersetzen möchtest:

     >>> np.argmin(b, axis=-1) array([[0, 0, 0], [1, 1, 1], [2, 2, 2]]) 

    Das erlaubt Ihnen, diese Elemente aus der choices zu wählen:

     >>> d = choices[np.argmin(b, axis=-1)] >>> d array([[ 1, 1, 1], [ 5, 5, 5], [10, 10, 10]]) 

    Für eine unsymmetrische Form:

    Sagen wir a Form (2, 5) :

     >>> a = np.arange(10).reshape((2, 5)) >>> a array([[0, 1, 2, 3, 4], [5, 6, 7, 8, 9]]) 

    Dann bekommst du:

     >>> b = np.abs(a[..., np.newaxis] - choices) >>> b array([[[ 1, 5, 10], [ 0, 4, 9], [ 1, 3, 8], [ 2, 2, 7], [ 3, 1, 6]], [[ 4, 0, 5], [ 5, 1, 4], [ 6, 2, 3], [ 7, 3, 2], [ 8, 4, 1]]]) 

    Das ist schwer zu lesen, aber was es sagt ist, hat b Form:

     >>> b.shape (2, 5, 3) 

    Die ersten beiden Dimensionen kamen aus der Form a , was auch (2, 5) . Die letzte Dimension ist die, die du gerade erstellt hast. Um eine bessere Idee zu bekommen:

     >>> b[:, :, 0] # = abs(a - 1) array([[1, 0, 1, 2, 3], [4, 5, 6, 7, 8]]) >>> b[:, :, 1] # = abs(a - 5) array([[5, 4, 3, 2, 1], [0, 1, 2, 3, 4]]) >>> b[:, :, 2] # = abs(a - 10) array([[10, 9, 8, 7, 6], [ 5, 4, 3, 2, 1]]) 

    Beachten Sie, wie b[:, :, i] die absolute Differenz zwischen a und choices[i] für jedes i = 1, 2, 3 .

    Hoffe, das hilft, dies ein wenig deutlicher zu erklären.

    Ich liebe den broadcasting und wäre auch so gegangen. Aber mit großen Arrays möchte ich einen anderen Ansatz mit np.searchsorted , der es Speicher effizient hält und somit Leistungsvorteile erzielt, wie so –

     def searchsorted_app(a, choices): lidx = np.searchsorted(choices, a, 'left').clip(max=choices.size-1) ridx = (np.searchsorted(choices, a, 'right')-1).clip(min=0) cl = np.take(choices,lidx) # Or choices[lidx] cr = np.take(choices,ridx) # Or choices[ridx] mask = np.abs(a - cl) > np.abs(a - cr) cl[mask] = cr[mask] return cl 

    Bitte beachten Sie, dass, wenn die Elemente in choices nicht sortiert sind, wir den zusätzlichen Argument- sorter mit np.searchsorted hinzufügen np.searchsorted .

    Runtime Test –

     In [160]: # Setup inputs ...: a = np.random.rand(100,100) ...: choices = np.sort(np.random.rand(100)) ...: In [161]: def broadcasting_app(a, choices): # @wwii's solution ...: return choices[np.argmin(np.abs(a[:,:,None] - choices),-1)] ...: In [162]: np.allclose(broadcasting_app(a,choices),searchsorted_app(a,choices)) Out[162]: True In [163]: %timeit broadcasting_app(a, choices) 100 loops, best of 3: 9.3 ms per loop In [164]: %timeit searchsorted_app(a, choices) 1000 loops, best of 3: 1.78 ms per loop 

    Verwandte Post: Finden Sie Elemente von Array ein am nächsten zu Elementen von Array zwei

    Python ist die beste Programmiersprache der Welt.