Skip to content

Fenêtre glissante Pandas : Rolling, Expanding et EWM

Updated on

Les moyennes mobiles et les signaux lissés sont au cœur de l’analyse de séries temporelles, pourtant beaucoup d’équipes ont du mal avec l’alignement des fenêtres, les valeurs manquantes et les boucles Python lentes.

  • Problème : Calculer les statistiques glissantes à la main est source d’erreurs et souvent mal aligné avec les horodatages.
  • Agitation : Les boucles et les décalages ad hoc produisent des erreurs de décalage d’un pas, des trous pour les périodes initiales et des notebooks lents.
  • Solution : Utiliser rolling, expanding et ewm avec les bons paramètres de fenêtre (min_periods, fenêtres basées sur le temps, center, adjust) pour obtenir des résultats corrects, rapides et vectorisés.

Want an AI agent that understands your pandas notebooks and rolling-window features?

RunCell is a JupyterLab AI agent that can read your code, analyze DataFrames, understand notebook context, debug errors, and even generate & execute code for you. It works directly inside JupyterLab—no switching windows or copy-pasting.

👉 Try RunCell: runcell.dev (opens in a new tab)


Aide-mémoire rapide

Type de fenêtreIdéal pourParamètres clés
rollingMoyennes mobiles, volatilité, fonctions de fenêtre personnaliséeswindow=3 (ou "7D"), min_periods, center, win_type, on
expandingStatistiques cumulées depuis le débutmin_periods
ewmLissage exponentiel ou métriques pondéréesspan, alpha, halflife, adjust, times

Données d’exemple

import pandas as pd
 
dates = pd.date_range("2024-01-01", periods=8, freq="D")
sales = pd.DataFrame({"date": dates, "revenue": [10, 12, 9, 14, 15, 13, 11, 16]})
sales = sales.set_index("date")

Fenêtres glissantes (taille fixe et basées sur le temps)

Fenêtres de taille fixe

sales["rev_ma3"] = (
    sales["revenue"]
    .rolling(window=3, min_periods=2)
    .mean()
)
  • min_periods contrôle le moment où les résultats commencent ; les premières lignes restent à NaN jusqu’à ce que le nombre minimal d’observations soit atteint.
  • center=True aligne la statistique au milieu de la fenêtre (pratique pour les graphiques).

Fenêtres basées sur le temps sur un index datetime ou une colonne on=

sales_reset = sales.reset_index()
sales_reset["rev_7d_mean"] = (
    sales_reset.rolling("7D", on="date")["revenue"].mean()
)
  • Utilisez des chaînes de durée ("7D", "48H") pour les échantillonnages irréguliers ; pandas choisit les lignes dans l’horizon de regard en arrière plutôt qu’un compte fixe.
  • Pour contrôler l’inclusion des bords avant/après, ajustez closed="left" ou "right" selon le besoin.

Fonctions de fenêtre personnalisées

sales["rev_range"] = (
    sales["revenue"].rolling(4).apply(lambda x: x.max() - x.min(), raw=True)
)

Mettez raw=True pour travailler avec des tableaux NumPy dans apply afin de gagner en performance.


Fenêtres cumulatives (Expanding)

sales["rev_cum_mean"] = sales["revenue"].expanding(min_periods=2).mean()
  • Utilisez expanding lorsqu’à chaque observation on veut voir tout l’historique jusqu’à ce point (moyenne glissante cumulative, ratios cumulés).
  • Combinez avec shift() pour comparer la nouvelle valeur à la moyenne historique.

Fenêtres à pondération exponentielle

sales["rev_ewm_span4"] = sales["revenue"].ewm(span=4, adjust=False).mean()
  • adjust=False utilise une formule récursive qui reflète le lissage typique des tableaux de bord analytiques.
  • halflife offre une décroissance intuitive : ewm(halflife=3) divise le poids par deux tous les 3 pas de temps.
  • Pour des horodatages irréguliers, passez times="date" (ou définissez l’index) pour pondérer selon les deltas temporels réels plutôt que le nombre de lignes.

Choisir la bonne fenêtre (antisèche)

ObjectifMéthode recommandéeRemarques
Lisser le bruit de court termerolling avec petite window et center=TrueFonctionne sur les colonnes numériques ; gardez min_periods ≥ 1 pour voir les premiers points
Totaux ou moyennes depuis le débutexpandingPas de fenêtre fixe ; idéal pour les KPI cumulatifs
Faire décroitre le poids des anciennes observationsewm(span=...)Plus efficace que de grandes fenêtres rolling pour les signaux de type momentum
Horodatages irréguliersrolling("7D", on="date") basé sur le temps ou ewm(..., times="date")Évite les biais dus aux jours plus densément échantillonnés
Génération de featuresrolling().agg(["mean","std","min","max"])Les agrégations multiples produisent rapidement des jeux de features propres

Conseils de performance et de justesse

  • Conservez les colonnes temporelles au format datetime64[ns] et définissez un index lorsque vous travaillez intensivement avec des fenêtres basées sur le temps.
  • Préférez les agrégations intégrées (mean, std, sum, count) à apply en Python pour de meilleures performances.
  • Évitez le biais prospectif : utilisez shift() avant rolling lorsque vous construisez des features pour l’apprentissage supervisé.
  • Combinez avec resample pour normaliser la fréquence avant d’appliquer rolling si les données sources sont irrégulières.

Les fenêtres rolling, expanding et exponentielles couvrent la plupart des besoins de lissage et de feature engineering sans boucles. Combinez-les avec pandas-to-datetime et pandas-resample pour des axes temporels propres, et vous obtiendrez des métriques rapides, fiables, prêtes pour les graphiques ou les modèles.