webentwicklung-frage-antwort-db.com.de

Peakfindungsalgorithmus für Python/SciPy

Ich kann selbst etwas schreiben, indem ich Nulldurchgänge der ersten Ableitung oder etwas anderes finde, aber es scheint eine Funktion zu sein, die häufig genug ist, um in Standardbibliotheken aufgenommen zu werden. Kennt jemand einen?

Meine spezielle Anwendung ist ein 2D-Array, aber normalerweise wird es zum Auffinden von Peaks in FFTs usw. verwendet.

Insbesondere gibt es bei diesen Arten von Problemen mehrere starke Spitzen und dann viele kleinere "Spitzen", die nur durch Rauschen verursacht werden, das ignoriert werden sollte. Dies sind nur Beispiele; nicht meine aktuellen Daten:

1-dimensionale Peaks:

 FFT output with peaks

2-dimensionale Peaks:

Radon transform output with circled peak

Der Peaksuchalgorithmus würde den Ort dieser Peaks (nicht nur ihrer Werte) finden und idealerweise den wahren Inter-Sample-Peak finden, nicht nur den Index mit dem Maximalwert, wahrscheinlich unter Verwendung von quadratischer Interpolation oder etwas.

In der Regel interessieren Sie sich nur für einige wenige starke Peaks, sodass sie entweder ausgewählt werden, weil sie über einem bestimmten Schwellenwert liegen, oder weil sie die ersten n Peaks einer geordneten Liste sind, geordnet nach Amplitude.

Wie gesagt, ich kann so etwas selber schreiben. Ich frage nur, ob es eine bereits vorhandene Funktion oder ein Paket gibt, von dem bekannt ist, dass es gut funktioniert.

Update:

Ich habe ein MATLAB-Skript übersetzt und es funktioniert anständig für den 1-D-Fall, könnte aber besser sein.

Aktualisiertes Update:

sixtenbe hat eine bessere version erstellt für den 1-D fall.

106
endolith

Ich glaube nicht, dass das, was Sie suchen, von SciPy bereitgestellt wird. Ich würde den Code in dieser Situation selbst schreiben.

Die Spline-Interpolation und das Glätten von scipy.interpolate sind ziemlich nett und könnten hilfreich sein, wenn Sie die Peaks anpassen und dann das Maximum finden.

8
Eric O Lebigot

Ich sehe ein ähnliches Problem, und ich habe herausgefunden, dass einige der besten Referenzen aus der Chemie stammen (von Peaks, die in Massenspektren gefunden werden). Um einen guten Überblick über Peaking-Finding-Algorithmen zu erhalten, lesen Sie this . Dies ist eine der klarsten Bewertungen der Spitzentechniken, die ich bisher gesehen habe. (Wavelets sind die besten, um solche Störgeräusche in geräuschvollen Daten zu finden.).

Es sieht so aus, als wären Ihre Gipfel klar definiert und nicht im Lärm verborgen. Da dies der Fall ist, würde ich die Verwendung von glatten savtizky-golay-Derivaten empfehlen, um die Peaks zu finden (wenn Sie nur die oben genannten Daten unterscheiden, haben Sie ein Durcheinander von falschen Positiven.) Dies ist eine sehr effektive Technik und ziemlich einfach zu implementieren (Sie benötigen eine Matrixklasse mit grundlegenden Operationen). Wenn Sie einfach den Nulldurchgang der ersten S-G-Ableitung finden, werden Sie glücklich sein.

42
Paul

In scipy gibt es eine Funktion namens scipy.signal.find_peaks_cwt, die sich anhört, als wäre sie für Ihre Bedürfnisse geeignet. Ich habe jedoch keine Erfahrung damit, ich kann sie nicht empfehlen.

http://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.find_peaks_cwt.html

18

Für diejenigen, die sich nicht sicher sind, welche Algorithmen für die Peakfindung in Python verwendet werden sollen, finden Sie hier einen schnellen Überblick über die Alternativen: https://github.com/MonsieurV/py-findpeaks

Ich wollte ein Äquivalent zu der MatLab-Funktion findpeaks. Ich habe herausgefunden, dass die Funktion detect_peaks von Marcos Duarte ein guter Fang ist.

Ziemlich einfach zu bedienen:

import numpy as np
from vector import vector, plot_peaks
from libs import detect_peaks
print('Detect peaks with minimum height and distance filters.')
indexes = detect_peaks.detect_peaks(vector, mph=7, mpd=2)
print('Peaks are: %s' % (indexes))

Was wird dir geben:

 detect_peaks results

14
Yoan Tournade

Die Funktion scipy.signal.find_peaks ist, wie der Name schon sagt, hilfreich. Aber es ist wichtig, die Parameter width, threshold, distanceund vor allem prominence gut zu verstehen, um eine gute Extraktion des Peaks zu erhalten.

Nach meinen Tests und der Dokumentation ist das Konzept von prominence das "nützliche Konzept", um die guten Spitzen zu halten und die lauten Spitzen zu verwerfen.

Was ist (topographische) Prominenz ? Es ist "die minimale Höhe, die erforderlich ist, um vom Gipfel in ein höheres Gelände zu gelangen", wie hier zu sehen ist:

 enter image description here

Die Idee ist:

Je höher die Prominenz, desto "wichtiger" ist der Peak.

Prüfung:

 enter image description here

Ich habe absichtlich einen (lauten) frequenzveränderlichen Sinus verwendet, da er viele Schwierigkeiten aufweist. Wir können sehen, dass der Parameter width hier nicht sehr nützlich ist, denn wenn Sie ein Minimum von width zu hoch einstellen, kann er keine sehr engen Peaks im Hochfrequenzteil verfolgen. Wenn Sie width zu niedrig einstellen, haben Sie viele unerwünschte Peaks im linken Teil des Signals. Gleiches Problem mit distance. threshold vergleicht nur die direkten Nachbarn, was hier nicht sinnvoll ist. prominence ist diejenige, die die beste Lösung bietet. Beachten Sie, dass Sie viele dieser Parameter kombinieren können!

Code:

import numpy as np
import matplotlib.pyplot as plt 
from scipy.signal import find_peaks, find_peaks_cwt

x = np.sin(2*np.pi*(2**np.linspace(2,10,1000))*np.arange(1000)/48000) + np.random.normal(0, 1, 1000) * 0.15
peaks, _ = find_peaks(x, distance=20)
peaks2, _ = find_peaks(x, prominence=1)      # BEST!
peaks3, _ = find_peaks(x, width=20)
peaks4, _ = find_peaks(x, threshold=0.4)     # Required vertical distance to its direct neighbouring samples, pretty useless
plt.subplot(2, 2, 1)
plt.plot(peaks, x[peaks], "xr"); plt.plot(x); plt.legend(['distance'])
plt.subplot(2, 2, 2)
plt.plot(peaks2, x[peaks2], "ob"); plt.plot(x); plt.legend(['prominence'])
plt.subplot(2, 2, 3)
plt.plot(peaks3, x[peaks3], "vg"); plt.plot(x); plt.legend(['width'])
plt.subplot(2, 2, 4)
plt.plot(peaks4, x[peaks4], "xk"); plt.plot(x); plt.legend(['threshold'])
plt.show()
11
Basj

Das Erkennen von Peaks in einem Spektrum auf eine zuverlässige Art und Weise wurde ziemlich genau untersucht, zum Beispiel die gesamte Arbeit an der Sinusmodellierung für Musik-/Audiosignale in den 80er Jahren. Suchen Sie in der Literatur nach "Sinusoidal Modeling".

Wenn Ihre Signale so sauber sind wie im Beispiel, sollte ein einfaches "Geben Sie mir etwas mit einer Amplitude, die höher ist als N Nachbarn", einigermaßen gut funktionieren. Wenn Sie rauschende Signale haben, ist es eine einfache, aber effektive Möglichkeit, Ihre Peaks in der Zeit zu betrachten und sie zu verfolgen: Sie erkennen dann Spektrallinien anstelle von Spektralpeaks. IOW, Sie berechnen die FFT in einem gleitenden Fenster Ihres Signals, um einen zeitlichen Satz von Spektrum (auch Spektrogramm genannt) zu erhalten. Sie betrachten dann die zeitliche Entwicklung des spektralen Peaks (d. H. In aufeinanderfolgenden Fenstern).

6

Es gibt standardmäßige statistische Funktionen und Methoden zum Auffinden von Ausreißern von Daten. Die Verwendung von Derivaten würde Ihre Sekunde lösen. Ich bin nicht sicher, ob es sich um eine Methode handelt, die sowohl kontinuierliche Funktionen als auch abgetastete Daten löst.

1
nullpointer

Zunächst einmal ist die Definition von "Peak" vage, wenn keine weiteren Angaben gemacht werden. Würden Sie beispielsweise für die folgende Serie 5-4-5 einen oder zwei Peaks nennen?

1-2-1-2-1-1-5-4-5-1-1-5-1

In diesem Fall benötigen Sie mindestens zwei Schwellwerte: 1) Ein hoher Schwellwert, oberhalb dessen ein Extremwert als Spitze registriert werden kann; und 2) eine niedrige Schwelle, so dass Extremwerte, die durch kleine Werte darunter getrennt sind, zwei Peaks werden.

Die Peakerkennung ist ein in der Literatur der Extremwerttheorie gut erforschtes Thema, das auch als "Deklinierung von Extremwerten" bezeichnet wird. Seine typischen Anwendungen umfassen das Identifizieren von Gefahrenereignissen auf der Grundlage kontinuierlicher Messungen von Umgebungsvariablen, z. Analyse der Windgeschwindigkeit zur Erkennung von Sturmereignissen.

0
Ian Liu