it-swarm.com.de

Finden des nächsten Werts und Rückgabe des Index des Arrays in Python

Ich habe diesen Beitrag gefunden: Python: ein Element in einem Array finden

und es geht darum, den Index eines Arrays durch Abgleichen der Werte zurückzugeben.

Auf der anderen Seite denke ich daran, etwas anderes zu tun. Ich möchte den nächstgelegenen Wert für den Zielwert finden. Zum Beispiel suche ich nach 4.2, aber ich weiß, dass es im Array keine 4.2 gibt, aber ich möchte den Index mit dem Wert 4.1 anstelle von 4.4 zurückgeben.

Was wäre der schnellste Weg, dies zu tun?

Ich denke daran, es auf die alte Art und Weise zu tun, wie ich es früher mit Matlab gemacht habe, das Array A verwendet, wo ich den Index von bis auf den Zielwert bringen und das Absolute davon nehmen und dann das Minimum auswählen möchte. Etwas wie das:-

[~,idx] = min(abs(A - target))

Das ist Matlab-Code, aber ich bin Neuling in Python, also denke ich, gibt es in Python eine schnelle Möglichkeit, dies zu tun?

Vielen Dank für deine Hilfe!

33
Harry MacDowel

Dies ähnelt der Verwendung von bisect_left, ermöglicht jedoch die Übergabe eines Arrays von Zielen 

def find_closest(A, target):
    #A must be sorted
    idx = A.searchsorted(target)
    idx = np.clip(idx, 1, len(A)-1)
    left = A[idx-1]
    right = A[idx]
    idx -= target - left < right - target
    return idx

Einige Erklärung:

Zunächst wird der allgemeine Fall: idx = A.searchsorted(target) für jede target einen Index zurückgegeben, sodass target zwischen A[index - 1] und A[index] liegt. Ich nenne diese left und right, damit wir wissen, dass left < target <= right. target - left < right - target ist True (oder 1), wenn sich das Ziel näher an left befindet, und False (oder 0), wenn sich das Ziel näher an right befindet.

Nun der Sonderfall: Wenn target kleiner ist als alle Elemente von A, idx = 0. idx = np.clip(idx, 1, len(A)-1) ersetzt alle Werte von idx <1 durch 1, also idx=1. In diesem Fall left = A[0], right = A[1] und wir wissen, dass target <= left <= right. Daher wissen wir, dass target - left <= 0 und right - target >= 0 so target - left < right - targetTrue ist, es sei denn target == left == right und idx - True = 0.

Es gibt einen weiteren Sonderfall, wenn target größer als alle Elemente von A ist. In diesem Fall ersetzen idx = A.searchsorted(target) und np.clip(idx, 1, len(A)-1) len(A) durch len(A) - 1, sodass idx=len(A) -1 und target - left < right - targetFalse beendet werden, sodass idx len(A) -1 zurückgibt. Ich lasse Sie durch die Logik selbst arbeiten.

Zum Beispiel:

In [163]: A = np.arange(0, 20.)

In [164]: target = np.array([-2, 100., 2., 2.4, 2.5, 2.6])

In [165]: find_closest(A, target)
Out[165]: array([ 0, 19,  2,  2,  3,  3])
31
Bi Rico

Der entsprechende Numpy-Code ist fast derselbe, außer dass Sie den Mindestindex mit numpy.argmin suchen.

idx = numpy.argmin(numpy.abs(A - target))
32
kennytm

Nun, mehr als zwei Jahre sind vergangen und ich habe eine sehr einfache Implementierung dieser URL gefunden: Finde den nächsten Wert in einem numpy-Array

Die Umsetzung ist:

def getnearpos(array,value):
    idx = (np.abs(array-value)).argmin()
    return idx   

Prost!! 

6
Harry MacDowel

Getestet und zeitgesteuert zwei Lösungen:

idx = np.searchsorted(sw, sCut)

und

idx = np.argmin(np.abs(sw - sCut))

für die Berechnung in einer zeitaufwendigen Methode. Timing war 113s für die Berechnung mit der zweiten Lösung und 132s für die Berechnung mit der ersten

4
octoback

Mögliche Lösung:

>>> a = [1.0, 3.2, -2.5, -3.1]
>>> i = -1.5
>>> diff = [(abs(i - x),idx) for (idx,x) in enumerate(a)]
>>> diff
[(2.5, 0), (4.7, 1), (1.0, 2), (1.6, 3)]
>>> diff.sort()
>>> diff
[(1.0, 2), (1.6, 3), (2.5, 0), (4.7, 1)]

Sie haben den Index des nächsten Werts in diff [0] [1]

2
Maciek
def Finder(myList, target)
    diff = ''
    index = None
    for i,num in enumerate(myList):
        if abs(target - num) < diff:
            diff = abs(target - num)
            index = i
    return index

Hoffe das hilft

EDIT:

Wenn Sie einen One-Liner haben möchten, könnte dies besser sein:

min(L, key=lambda x: abs(target-x))
0
inspectorG4dget