485 Stimmen

Den nächstgelegenen Wert in einem Numpy-Array finden

Gibt es einen numpy-thonischen Weg, z.B. eine Funktion, um die nächstgelegener Wert in einem Array?

Ejemplo:

np.find_nearest( array, value )

19voto

Onasafari Punkte 458

Hier ist eine Erweiterung, um den nächstgelegenen Vektor in einem Array von Vektoren zu finden.

import numpy as np

def find_nearest_vector(array, value):
  idx = np.array([np.linalg.norm(x+y) for (x,y) in array-value]).argmin()
  return array[idx]

A = np.random.random((10,2))*100
""" A = array([[ 34.19762933,  43.14534123],
   [ 48.79558706,  47.79243283],
   [ 38.42774411,  84.87155478],
   [ 63.64371943,  50.7722317 ],
   [ 73.56362857,  27.87895698],
   [ 96.67790593,  77.76150486],
   [ 68.86202147,  21.38735169],
   [  5.21796467,  59.17051276],
   [ 82.92389467,  99.90387851],
   [  6.76626539,  30.50661753]])"""
pt = [6, 30]  
print find_nearest_vector(A,pt)
# array([  6.76626539,  30.50661753])

11voto

Nick Crawford Punkte 4986

Wenn Sie Numpy nicht verwenden möchten, reicht dies aus:

def find_nearest(array, value):
    n = [abs(i-value) for i in array]
    idx = n.index(min(n))
    return array[idx]

10voto

ryggyr Punkte 3131

Hier ist eine Version, die mit einem nicht-skalaren "Werte"-Array umgehen kann:

import numpy as np

def find_nearest(array, values):
    indices = np.abs(np.subtract.outer(array, values)).argmin(0)
    return array[indices]

Oder eine Version, die einen numerischen Typ (z. B. int, float) zurückgibt, wenn die Eingabe skalar ist:

def find_nearest(array, values):
    values = np.atleast_1d(values)
    indices = np.abs(np.subtract.outer(array, values)).argmin(0)
    out = array[indices]
    return out if len(out) > 1 else out[0]

9voto

efirvida Punkte 4209

Hier ist eine Version mit Scipy für @Ari Onasafari, Antwort " um den nächstgelegenen Vektor in einer Reihe von Vektoren zu finden "

In [1]: from scipy import spatial

In [2]: import numpy as np

In [3]: A = np.random.random((10,2))*100

In [4]: A
Out[4]:
array([[ 68.83402637,  38.07632221],
       [ 76.84704074,  24.9395109 ],
       [ 16.26715795,  98.52763827],
       [ 70.99411985,  67.31740151],
       [ 71.72452181,  24.13516764],
       [ 17.22707611,  20.65425362],
       [ 43.85122458,  21.50624882],
       [ 76.71987125,  44.95031274],
       [ 63.77341073,  78.87417774],
       [  8.45828909,  30.18426696]])

In [5]: pt = [6, 30]  # <-- the point to find

In [6]: A[spatial.KDTree(A).query(pt)[1]] # <-- the nearest point 
Out[6]: array([  8.45828909,  30.18426696])

#how it works!
In [7]: distance,index = spatial.KDTree(A).query(pt)

In [8]: distance # <-- The distances to the nearest neighbors
Out[8]: 2.4651855048258393

In [9]: index # <-- The locations of the neighbors
Out[9]: 9

#then 
In [10]: A[index]
Out[10]: array([  8.45828909,  30.18426696])

8voto

aph Punkte 1615

Für große Arrays ist die (ausgezeichnete) Antwort von @Demitri viel schneller als die derzeit als beste markierte Antwort. Ich habe seinen genauen Algorithmus auf die folgenden zwei Arten angepasst:

  1. Die folgende Funktion funktioniert unabhängig davon, ob das Eingabefeld sortiert ist oder nicht.

  2. Die folgende Funktion gibt die Index des Eingabefeldes, das dem nächstgelegenen Wert entspricht, was etwas allgemeiner ist.

Beachten Sie, dass die unten stehende Funktion auch einen speziellen Randfall behandelt, der zu einem Fehler in der von @Demitri geschriebenen Originalfunktion führen würde. Ansonsten ist mein Algorithmus mit seinem identisch.

def find_idx_nearest_val(array, value):
    idx_sorted = np.argsort(array)
    sorted_array = np.array(array[idx_sorted])
    idx = np.searchsorted(sorted_array, value, side="left")
    if idx >= len(array):
        idx_nearest = idx_sorted[len(array)-1]
    elif idx == 0:
        idx_nearest = idx_sorted[0]
    else:
        if abs(value - sorted_array[idx-1]) < abs(value - sorted_array[idx]):
            idx_nearest = idx_sorted[idx-1]
        else:
            idx_nearest = idx_sorted[idx]
    return idx_nearest

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X