HOWTO · Python
Implementieren eines Tiefpassfilters in Python
Erfahren Sie, wie Sie abgetastete Daten in Python mit einem SciPy-Butterworth-Filter, einem gleitenden Mittelwert oder einer Gauß-Glättung filtern und wie Grenzfrequenz und Abtastgrenzen zu verstehen sind.
Auf dieser Seite
Ein Tiefpassfilter lässt niederfrequente Signalanteile passieren und schwächt höherfrequente Anteile ab; er entfernt nicht unbedingt jeden Anteil oberhalb seiner Grenzfrequenz. Bei abgetasteten Daten müssen Grenzfrequenz und Abtastfrequenz in derselben Einheit angegeben werden. Dieser Leitfaden zeigt drei Möglichkeiten, ein eindimensionales Signal mit NumPy und SciPy zu filtern oder zu glätten.
Die folgenden Beispiele sind in sich vollständig, werden hier aber nicht ausgeführt, und es werden keine Ergebnisse dafür gezeigt. Installieren Sie NumPy, SciPy und Matplotlib in Ihrer Python-Umgebung, bevor Sie die Beispiele ausführen.
Einen SciPy-Butterworth-Filter mit festgelegter Grenzfrequenz verwenden
Ein Butterworth-Filter besitzt einen maximal flachen Durchlassbereich. Legen Sie die Grenzfrequenz unterhalb der Nyquist-Frequenz fest, die der Hälfte der Abtastfrequenz entspricht. Im Beispiel beträgt fs 500 Abtastwerte pro Sekunde und die Grenzfrequenz 100 Hz. Wenn Sie fs an scipy.signal.butter übergeben, können Sie die Grenzfrequenz in derselben Einheit angeben. Die Filterordnung bestimmt, wie steil der Übergang ist: Eine höhere Ordnung führt zu einem steileren Abfall, macht das Filterverhalten aber empfindlicher gegenüber Transienten und numerischen Effekten.
Dieses Beispiel verwendet Sektionen zweiter Ordnung und sosfiltfilt, um das Signal vorwärts und rückwärts zu filtern. So wird bei einer Offline-Analyse eine Phasenverzögerung vermieden. Dafür werden Daten aus beiden Richtungen benötigt, und die Randbereiche eines endlichen Signals können beeinflusst werden. Für Streaming oder Echtzeitdaten verwenden Sie ein kausales Filter wie sosfilt und berücksichtigen dessen Phasenverzögerung und Einschwingvorgang.
import matplotlib.pyplot as plt
import numpy as np
from scipy.signal import butter, sosfiltfilt
fs = 500.0
cutoff = 100.0
order = 4
time = np.arange(500) / fs
signal = np.sin(2 * np.pi * 10 * time) + 0.5 * np.sin(2 * np.pi * 180 * time)
sections = butter(order, cutoff, btype="lowpass", fs=fs, output="sos")
filtered = sosfiltfilt(sections, signal)
plt.plot(time, signal, label="input")
plt.plot(time, filtered, label="filtered")
plt.xlabel("Time (seconds)")
plt.ylabel("Amplitude")
plt.legend()
plt.tight_layout()
plt.show()
Passen Sie cutoff und order an das Signal und die Frequenzen an, die Sie erhalten möchten. sosfiltfilt ist für Offline-Daten vorgesehen; sein Ergebnis ist nicht mit dem eines kausalen Echtzeitfilters austauschbar.
Einen Tiefpassfilter mit gleitendem Mittelwert anwenden
Ein gleitender Mittelwert ersetzt jeden Punkt durch den Mittelwert eines Fensters fester Länge. Das ist eine einfache Glättungsmethode, aber kein Butterworth-Filter mit einer festgelegten Grenzfrequenzantwort. Im NumPy-Modus valid enthält das Ergebnis nur vollständige Fenster und ist daher um window_size - 1 Abtastwerte kürzer als die Eingabe. Richten Sie beim Plotten die zugehörigen Zeitwerte entsprechend aus.
import matplotlib.pyplot as plt
import numpy as np
fs = 100.0
window_size = 5
time = np.arange(100) / fs
signal = np.sin(2 * np.pi * 3 * time) + 0.2 * np.sin(2 * np.pi * 25 * time)
weights = np.ones(window_size) / window_size
smoothed = np.convolve(signal, weights, mode="valid")
smoothed_time = time[window_size - 1:]
plt.plot(time, signal, label="input")
plt.plot(smoothed_time, smoothed, label="moving average")
plt.xlabel("Time (seconds)")
plt.ylabel("Amplitude")
plt.legend()
plt.tight_layout()
plt.show()
Wählen Sie eine positive Fenstergröße, die höchstens so groß wie die Signallänge ist. Mit einem größeren Fenster werden mehr Abtastwerte gemittelt und das Signal stärker geglättet; zugleich werden Änderungen verbreitert und die Ausrichtung des Fensterergebnisses verschoben. Berücksichtigen Sie bei einer zentrierten Ausrichtung die Verzögerung des Fensters, wenn Sie die Zeitwerte interpretieren.
Abtastdaten mit einem Gauß-Filter glätten
Ein eindimensionaler Gauß-Filter gewichtet benachbarte Abtastwerte mithilfe eines gaußförmigen Kerns. Bei scipy.ndimage.gaussian_filter1d wird sigma in Abtastwerten angegeben, nicht in Sekunden oder Hertz. Wenn nötig, rechnen Sie eine gewünschte Zeitspanne anhand der Abtastfrequenz in Abtastwerte um. Die Gauß-Glättung eignet sich für eine allgemeine Glättung, erzeugt aber keine scharf definierte Grenzfrequenz.
import matplotlib.pyplot as plt
import numpy as np
from scipy.ndimage import gaussian_filter1d
fs = 100.0
sigma_seconds = 0.04
time = np.arange(100) / fs
signal = np.sin(2 * np.pi * 3 * time) + 0.2 * np.sin(2 * np.pi * 25 * time)
smoothed = gaussian_filter1d(signal, sigma=sigma_seconds * fs)
plt.plot(time, signal, label="input")
plt.plot(time, smoothed, label="Gaussian smoothed")
plt.xlabel("Time (seconds)")
plt.ylabel("Amplitude")
plt.legend()
plt.tight_layout()
plt.show()
Im Beispiel wird eine Glättungsdauer von 0,04 Sekunden in vier Abtastwerte umgerechnet. Standardmäßig werden die Signalenden durch Spiegelung behandelt. Wählen Sie einen anderen mode, wenn Ihre Daten ein anderes Randmodell erfordern, und interpretieren Sie die Randbereiche mit Vorsicht.
Ein Filter auswählen und seine Grenzen berücksichtigen
Verwenden Sie einen Butterworth-Filter, wenn Sie eine definierte Frequenzantwort benötigen und die Abtastfrequenz kennen. Ein gleitender Mittelwert eignet sich für eine einfache Glättung über ein festes Fenster; eine Gauß-Glättung ist passend, wenn eine glatte lokale Gewichtung genügt. Diese Methoden haben unterschiedliche Frequenzantworten, Verzögerungen und Randverhalten. Vergleichen Sie daher das Ergebnis mit den ursprünglichen Daten und prüfen Sie, ob die für Ihre Aufgabe wichtigen Merkmale sichtbar bleiben.
Bei abgetasteten Daten entspricht die Nyquist-Frequenz der Hälfte der Abtastfrequenz. Die Grenzfrequenz eines Tiefpassfilters muss darunter liegen, und die Abtastfrequenz muss hoch genug sein, um die interessierenden Frequenzen abzubilden. Kein Filter kann Informationen wiederherstellen, die bei der Abtastung nicht erfasst wurden. Eine Offline-Filterung vorwärts und rückwärts kann die Phasenverschiebung verringern; kausale Filter eignen sich für Streaming, verursachen aber Verzögerungen und Einschwingverhalten. Bei endlichen Datensätzen hängen die Filterergebnisse nahe den Rändern außerdem stärker von der Auffüllung und den Anfangsbedingungen ab.
FAQ
Was bewirkt ein Tiefpassfilter?
Je nach Frequenzantwort lässt es niederfrequente Signalanteile passieren und schwächt höherfrequente Anteile ab. Die Grenzfrequenz kennzeichnet einen Übergang in dieser Antwort; sie bedeutet nicht, dass alle höheren Frequenzen vollständig verschwinden.
Wann sollte ich einen Tiefpassfilter verwenden?
Verwenden Sie ihn, wenn höherfrequente Schwankungen für Ihre Aufgabe als Rauschen gelten und Abtastfrequenz sowie Grenzfrequenz bekannt sind. Prüfen Sie, ob die Glättung keine bedeutsamen schnellen Signaländerungen entfernt.
Worin unterscheidet sich ein Butterworth-Filter von einem gleitenden Mittelwert?
Ein Butterworth-Filter wird anhand einer Grenzfrequenz, der Abtastfrequenz und der Filterordnung entworfen. Ein gleitender Mittelwert verwendet eine feste Anzahl von Abtastwerten pro Fenster und hat eine andere Frequenzantwort. Die Fensterlänge ist daher kein direkter Ersatz für eine Butterworth-Grenzfrequenz.
Kann ich diese Filter für Echtzeitdaten verwenden?
Ein kausales Filter kann eintreffende Abtastwerte verarbeiten; seine Phasenverzögerung und sein Einschwingvorgang müssen jedoch berücksichtigt werden. Die Vorwärts-Rückwärts-Methode im Butterworth-Beispiel benötigt den gesamten Datensatz und ist für die Offline-Verarbeitung gedacht. Einen gleitenden Mittelwert können Sie bei eintreffenden Abtastwerten laufend aktualisieren, wenn Sie Fenster und Ausrichtung korrekt handhaben.
Welche Python-Bibliotheken kann ich verwenden?
NumPy stellt Arrays und Faltungsfunktionen bereit; SciPy bietet Funktionen für den Entwurf von Butterworth-Filtern und die Gauß-Glättung. Mit Matplotlib können Sie Eingabe- und gefilterte Signale zur Prüfung plotten.