HOWTO · Python
Spitzenwerte finden in Python
Dieses Tutorial demonstriert die Peak-Findungsalgorithmen in Python.
Auf dieser Seite
Ein lokales Maximum ist ein Messwert, der größer als benachbarte Werte ist; er muss nicht der größte Wert der gesamten Reihe sein. Bei einer eindimensionalen Folge können Sie für eine einfache Lösung jeden inneren Wert mit seinen Nachbarn vergleichen oder scipy.signal.find_peaks() verwenden, wenn Sie Kandidaten filtern möchten. Diese Funktionen geben nullbasierte Indizes innerhalb der ursprünglichen Daten zurück. Mit diesen Indizes können Sie die Spitzenwerte abrufen.
Einfache lokale Maxima mit NumPy finden
Dieses kompakte Beispiel verwendet ein eindimensionales Array und gibt für jedes erkannte Maximum den Index und den zugehörigen Wert aus.
import numpy as np
data = np.array([1, 3, 7, 1, 2, 6, 0, 5, 0, 4])
local_maxima = (data[1:-1] > data[:-2]) & (data[1:-1] > data[2:])
indices = np.flatnonzero(local_maxima) + 1
print("indices:", indices.tolist())
print("values:", data[indices].tolist())
indices: [2, 5, 7]
values: [7, 6, 5]
Die beiden Vergleiche verlangen, dass ein Wert strikt größer als seine beiden direkten Nachbarn ist. Der Ausschnitt vergleicht nur innere Werte; das erste und das letzte Element kommen daher nicht als Kandidaten infrage. Gleich hohe Plateaus werden ebenfalls ausgeschlossen. Der Indexversatz ordnet das kürzere Vergleichsarray wieder den Positionen in data zu. Dieser NumPy-Ansatz eignet sich, wenn diese genaue Regel zu Ihren Daten passt. Für diese Eingabe lauten die erkannten Indizes [2, 5, 7], die zugehörigen Werte sind [7, 6, 5].
Spitzenwerte mit scipy.signal.find_peaks() filtern
Für eine allgemeine Suche nach Spitzenwerten in einer eindimensionalen Folge gibt SciPy scipy.signal.find_peaks() die Indizes lokaler Maxima zurück und kann zusätzlich optionale Bedingungen anwenden. Das folgende Beispiel wählt Spitzenwerte ab einer Höhe von 3 aus und gibt sowohl ihre Indizes als auch ihre Werte aus:
import numpy as np
from scipy.signal import find_peaks
data = np.array([1, 3, 7, 1, 2, 6, 0, 5, 0, 4])
indices, properties = find_peaks(data, height=3, distance=2, prominence=1)
print("indices:", indices.tolist())
print("values:", data[indices].tolist())
indices: [2, 5, 7]
values: [7, 6, 5]
height filtert nach dem Wert des Spitzenwerts, distance legt den Mindestabstand zwischen beibehaltenen Spitzenwerten in Abtastwerten fest und prominence beschreibt, wie deutlich sich ein Spitzenwert von seiner Umgebung abhebt. distance beeinflusst, welche Spitzenwerte beibehalten werden; es wird nicht als Eigenschaft zurückgegeben. Weitere optionale Bedingungen sind unter anderem width und threshold. SciPy gibt Indizes und ein Eigenschaften-Dictionary mit den Eigenschaften zurück, die für angeforderte und anwendbare Bedingungen ermittelt wurden. Für diese Eingabe und diese Argumente sind die zurückgegebenen Indizes [2, 5, 7] und die Werte [7, 6, 5]. Wählen Sie Bedingungen, die das Signal passend beschreiben, statt jedes lokale Maximum automatisch als relevant anzusehen.
Relative Extrema mit scipy.signal.argrelextrema() finden
Verwenden Sie scipy.signal.argrelextrema(), wenn Sie Werte innerhalb einer festgelegten Nachbarschaft miteinander vergleichen möchten. Übergeben Sie einen Vergleichsoperator wie np.greater, um Maxima zu finden, und setzen Sie order auf die Anzahl der Werte auf jeder Seite, die in den Vergleich einbezogen werden. Das Ergebnis ist ein Tupel mit Index-Arrays, eines für jede Eingabedimension. Bei einem eindimensionalen Array greifen Sie mit [0] auf die Indizes zu.
import numpy as np
from scipy.signal import argrelextrema
data = np.array([1, 3, 7, 1, 2, 6, 0, 5, 0, 4])
indices = argrelextrema(data, np.greater, order=1)[0]
print("indices:", indices.tolist())
print("values:", data[indices].tolist())
indices: [2, 5, 7]
values: [7, 6, 5]
Mit order=1 wird jeder Kandidat mit dem jeweils benachbarten Wert auf beiden Seiten verglichen. Ein größerer Wert für order berücksichtigt eine breitere Nachbarschaft und kann daher eine andere Menge relativer Extrema ergeben. Für diese Eingabe mit order=1 lauten die zurückgegebenen Indizes [2, 5, 7], die zugehörigen Werte sind [7, 6, 5].
detecta.detect_peaks() als Alternative verwenden
detecta.detect_peaks() ist eine Alternative eines Drittanbieters für eindimensionale Folgen. Installieren Sie die Abhängigkeit in Ihrer Projektumgebung mit python -m pip install detecta und übergeben Sie anschließend die Beispieldaten an detect_peaks():
data = [1, 3, 7, 1, 2, 6, 0, 5, 0, 4]
try:
from detecta import detect_peaks
except ImportError:
print("Install detecta with: python -m pip install detecta")
else:
indices = detect_peaks(data)
values = [data[index] for index in indices]
print("indices:", list(indices))
print("values:", values)
Für die Beispielsequenz werden die nullbasierten Spitzenwertindizes [2, 5, 7] erwartet; sie entsprechen den Werten [7, 6, 5]. Die bereitgestellten Laufzeitnachweise bestätigen nur die Meldung zur fehlenden Abhängigkeit. Dieses detecta-Ergebnis ist daher ein erwarteter Vergleich und keine beobachtete Laufzeitausgabe. Behalten Sie die Importprüfung bei: Wenn detecta nicht verfügbar ist, gibt das Beispiel den Installationsbefehl aus, statt die Erkennung zu versuchen.
Eine Methode zur Erkennung von Spitzenwerten auswählen
Verwenden Sie den NumPy-Vergleich, wenn strikt größere Werte gegenüber den direkten Nachbarn die vollständige Regel sind, die Sie benötigen, und Sie die Logik direkt nachvollziehen möchten. Wählen Sie scipy.signal.find_peaks(), wenn Filterbedingungen wie Höhe, Abstand, Prominenz oder Breite wichtig sind. Verwenden Sie scipy.signal.argrelextrema(), wenn die Vergleichsnachbarschaft und der Vergleichsoperator für Ihre Definition eines Extremums entscheidend sind. Ziehen Sie detecta.detect_peaks() in Betracht, wenn die API des Drittanbieterpakets zu Ihrem Projekt passt und Sie diese Abhängigkeit hinzufügen möchten.
Alle zurückgegebenen Positionen sind nullbasierte Indizes innerhalb der Eingabefolge. Vergleichen Sie die Definition der jeweiligen Methode mit Ihren Daten, bevor Sie das Ergebnis interpretieren: Der Umgang mit Endpunkten und Plateaus sowie die Filterbedingungen unterscheiden sich. Die obigen Beispiele behandeln lokale Maxima in eindimensionalen numerischen Daten; für mehrdimensionale Daten benötigen Sie eine Methode, die für diese Datenform ausgelegt ist. Beschriftungen in den unveränderten Code- und Ausgabeblöcken bleiben auf Englisch.