HOWTO · Python

Implémenter un filtre passe-bas en Python

Apprenez à filtrer des données échantillonnées en Python avec un filtre Butterworth de SciPy, une moyenne mobile ou un lissage gaussien, et comprenez la fréquence de coupure et les limites d’échantillonnage.

Sur cette page

Un filtre passe-bas laisse passer les composantes de basse fréquence et atténue celles de fréquence plus élevée ; il ne supprime pas nécessairement toutes les composantes situées au-dessus de sa fréquence de coupure. Pour des données échantillonnées, choisissez une fréquence de coupure exprimée dans les mêmes unités que la fréquence d’échantillonnage. Ce guide présente trois façons de filtrer ou de lisser un signal unidimensionnel avec NumPy et SciPy.

Pour replacer le filtrage parmi les autres techniques de traitement de données, consultez notre tutoriel Python, qui regroupe les guides par tâche.

Les exemples ci-dessous sont autonomes, mais ils ne sont pas exécutés ici et aucun résultat n’est affiché pour eux. Installez NumPy, SciPy et Matplotlib dans votre environnement Python avant de les lancer.

Utiliser un filtre Butterworth de SciPy avec une fréquence de coupure définie

Un filtre Butterworth présente une bande passante aussi plate que possible. Réglez la fréquence de coupure en dessous de la fréquence de Nyquist, qui correspond à la moitié de la fréquence d’échantillonnage. Dans l’exemple, fs vaut 500 échantillons par seconde et la fréquence de coupure est de 100 Hz. Le passage de fs à scipy.signal.butter permet d’exprimer la fréquence de coupure dans ces mêmes unités. L’ordre détermine la raideur de la transition : un ordre plus élevé donne une atténuation plus rapide, mais augmente la sensibilité aux transitoires et aux effets numériques.

Cet exemple utilise des sections du second ordre et sosfiltfilt, qui applique le filtrage dans les deux sens. Cette méthode évite le déphasage pour une analyse hors ligne, mais nécessite les données dans les deux directions et peut affecter les extrémités d’un signal fini. Pour traiter des données en flux ou en temps réel, utilisez un filtre causal comme sosfilt et tenez compte de son déphasage et de son transitoire de démarrage.

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()

Ajustez cutoff et order en fonction du signal et des fréquences que vous souhaitez conserver. sosfiltfilt est destiné au traitement hors ligne ; son résultat n’est pas interchangeable avec celui d’un filtre causal utilisé en temps réel.

Appliquer un filtre passe-bas par moyenne mobile

Une moyenne mobile remplace chaque point par la moyenne d’une fenêtre de taille fixe. C’est une méthode de lissage simple, et non un filtre Butterworth dont la réponse est définie par une fréquence de coupure. Avec le mode de convolution valid de NumPy, le résultat ne contient que des fenêtres complètes : il comporte donc window_size - 1 échantillons de moins que le signal d’entrée. Lors du tracé, alignez les valeurs temporelles en conséquence.

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()

Choisissez une taille de fenêtre positive qui ne dépasse pas la longueur du signal. Plus la fenêtre est grande, plus le nombre d’échantillons moyennés augmente et plus le lissage est marqué ; en contrepartie, les variations sont étalées et l’alignement du résultat par fenêtre est décalé. Pour un alignement centré, tenez compte du retard de la fenêtre lorsque vous interprétez les valeurs temporelles.

Utiliser un filtre gaussien pour lisser des données échantillonnées

Un filtre gaussien unidimensionnel pondère les échantillons voisins à l’aide d’un noyau de forme gaussienne. Dans scipy.ndimage.gaussian_filter1d, sigma est exprimé en échantillons, et non en secondes ou en hertz. Si nécessaire, convertissez l’échelle temporelle souhaitée en nombre d’échantillons à l’aide de la fréquence d’échantillonnage. Le lissage gaussien convient à un lissage général, mais ne crée pas de fréquence de coupure définie et abrupte.

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()

L’exemple convertit une durée de lissage de 0,04 seconde en quatre échantillons. Par défaut, les extrémités sont traitées par réflexion du signal ; choisissez un autre mode si vos données supposent un comportement différent aux extrémités, et interprétez celles-ci avec prudence.

Choisir un filtre et comprendre ses limites

Choisissez un filtre Butterworth si vous avez besoin d’une réponse en fréquence définie et connaissez la fréquence d’échantillonnage. Optez pour une moyenne mobile si vous recherchez un lissage simple par fenêtre, ou pour un lissage gaussien lorsqu’une pondération locale régulière convient. Ces méthodes ont des réponses, des retards et des comportements aux extrémités différents : comparez le résultat aux données d’origine et vérifiez que les caractéristiques importantes pour votre tâche restent visibles.

Pour des données échantillonnées, la fréquence de Nyquist correspond à la moitié de la fréquence d’échantillonnage. La fréquence de coupure d’un filtre passe-bas doit être inférieure à celle de Nyquist, et la fréquence d’échantillonnage doit être assez élevée pour représenter les fréquences qui vous intéressent. Aucun filtre ne peut récupérer des informations qui n’ont pas été capturées lors de l’échantillonnage. Le filtrage hors ligne dans les deux sens peut réduire le déphasage, tandis qu’un filtrage causal convient au traitement en flux, mais introduit un retard et des effets au démarrage. Dans un enregistrement de durée finie, le remplissage et les conditions initiales influencent davantage les résultats près des extrémités.

FAQ

Que fait un filtre passe-bas ?

Selon sa réponse, il laisse passer les composantes de basse fréquence et atténue celles de fréquence plus élevée. La fréquence de coupure marque une transition dans cette réponse ; elle ne signifie pas que toutes les fréquences supérieures disparaissent complètement.

Quand faut-il utiliser un filtre passe-bas ?

Utilisez-en un lorsque les variations de fréquence plus élevée constituent du bruit pour votre tâche et que la fréquence d’échantillonnage ainsi que la fréquence de coupure sont connues. Vérifiez que le lissage ne supprime pas des variations rapides du signal qui ont du sens.

Quelle est la différence entre un filtre Butterworth et une moyenne mobile ?

Un filtre Butterworth est défini à partir d’une fréquence de coupure, d’une fréquence d’échantillonnage et d’un ordre. Une moyenne mobile utilise un nombre fixe d’échantillons par fenêtre et possède une réponse en fréquence différente ; la longueur de sa fenêtre ne remplace pas directement la fréquence de coupure d’un filtre Butterworth.

Ces filtres peuvent-ils traiter des données en temps réel ?

Un filtre causal peut traiter les échantillons à mesure qu’ils arrivent, mais son déphasage et son transitoire de démarrage doivent être pris en compte. La méthode de filtrage dans les deux sens de l’exemple Butterworth nécessite l’enregistrement complet et est destinée au traitement hors ligne. Une moyenne mobile peut être mise à jour à l’arrivée des échantillons, à condition de gérer sa fenêtre et son alignement.

Quelles bibliothèques Python puis-je utiliser ?

NumPy fournit les tableaux et la convolution, tandis que SciPy propose des fonctions de conception de filtres Butterworth et de lissage gaussien. Matplotlib permet de tracer les signaux d’entrée et filtrés pour les examiner.