Weiter zum Inhalt

Gleitende Durchschnitte in pandas

Lerne, wie du mit einem gleitenden bzw. Rolling Average Trends erkennst und Zeitreihendaten sinnvoll auswertest.
Aktualisiert 18. Sept. 2026  · 8 Min. lesen

Mit KI erkunden

ChatGPTClaudePerplexity

Einführung

Ein gleitender Durchschnitt, auch Rolling- oder Running Average genannt, wird verwendet, um Zeitreihendaten zu analysieren, indem Durchschnitte verschiedener Teilmengen des gesamten Datensatzes berechnet werden. Da dabei über die Zeit der Durchschnitt des Datensatzes gebildet wird, spricht man auch von Moving Mean (MM) oder Rolling Mean.

Es gibt verschiedene Möglichkeiten, den gleitenden Durchschnitt zu berechnen. Eine davon ist, eine feste Teilmenge aus einer vollständigen Zahlenreihe zu nehmen. Der erste gleitende Durchschnitt wird berechnet, indem der Durchschnitt der ersten festen Teilmenge gebildet wird. Anschließend wird die Teilmenge verschoben, indem du nach vorn rückst zur nächsten festen Teilmenge (der neue Wert kommt hinzu, der älteste Wert der Reihe fällt heraus).

Der gleitende Durchschnitt wird meist bei Zeitreihendaten eingesetzt, um kurzfristige Schwankungen herauszufiltern und gleichzeitig längerfristige Trends sichtbar zu machen.

Beispiele für Zeitreihendaten sind Aktienkurse, Wetterberichte, Luftqualität, Bruttoinlandsprodukt, Beschäftigung usw.

Allgemein glättet der gleitende Durchschnitt die Daten.

Der gleitende Durchschnitt ist die Grundlage vieler Algorithmen, etwa des Autoregressive Integrated Moving Average Model (ARIMA), das Moving Averages nutzt, um Vorhersagen für Zeitreihen zu treffen.

Es gibt verschiedene Arten gleitender Durchschnitte:

  • Einfacher gleitender Durchschnitt (Simple Moving Average, SMA): Der einfache gleitende Durchschnitt nutzt ein gleitendes Fenster, um über eine festgelegte Anzahl von Zeitperioden den Durchschnitt zu bilden. Er ist ein gleich gewichteter Mittelwert der vorherigen n Datenpunkte.

    Um SMA besser zu verstehen, nehmen wir eine Folge von n Werten:

    sequence of n values

    Dann ist der gleich gewichtete gleitende Durchschnitt für n Datenpunkte im Kern der Mittelwert der vorherigen M Datenpunkte, wobei M die Größe des gleitenden Fensters ist:

    simple moving average calculation 1

    Für die nachfolgenden Werte des gleitenden Durchschnitts wird jeweils ein neuer Wert zur Summe addiert und der älteste Zeitraum entfernt. Da du bereits den Durchschnitt der vorherigen Perioden hast, ist keine vollständige Neusummation nötig:

    simple moving average calculation 2
  • Kumulativer gleitender Durchschnitt (Cumulative Moving Average, CMA): Anders als beim einfachen gleitenden Durchschnitt, der die älteste Beobachtung verwirft, sobald eine neue hinzukommt, berücksichtigt der kumulative gleitende Durchschnitt alle bisherigen Beobachtungen. CMA eignet sich weniger gut, um Trends zu analysieren und Daten zu glätten. Der Grund: Er mittelt alle bisherigen Daten bis zum aktuellen Punkt, also ein gleich gewichteter Mittelwert der Folge von n Werten:
    sequence of n values 2
    bis zum aktuellen Zeitpunkt ergibt sich:
    cumulative moving average 1
    Analog kann die Aktualisierung des kumulativen Durchschnitts für jeden neuen Wert mit folgender Formel berechnet werden:
    cumulative moving average 2
  • Exponentieller gleitender Durchschnitt (Exponential Moving Average, EMA): Im Unterschied zu SMA und CMA gewichtet der exponentielle gleitende Durchschnitt jüngste Werte stärker. Dadurch kann er Trends oft schneller und genauer nachzeichnen. Die Reaktion des EMA ist direkt proportional zum Muster der Daten.

Da EMAs neuere Daten stärker gewichten als ältere, reagieren sie sensibler auf aktuelle Preisänderungen als SMAs. Die Ergebnisse sind dadurch zeitnäher, weshalb EMA oft bevorzugt wird.

Genug Theorie, oder? Lass uns zur praktischen Umsetzung des gleitenden Durchschnitts springen.

Moving Average mit Zeitreihendaten umsetzen

Einfacher gleitender Durchschnitt (SMA)

Erst erstellen wir Dummy-Zeitreihendaten und implementieren SMA nur mit Python.

Angenommen, die Nachfrage nach einem Produkt wird über 12 Monate (1 Jahr) beobachtet. Du sollst gleitende Durchschnitte für Fenster von 3 und 4 Monaten berechnen.

Modul importieren

import pandas as pd
import numpy as np
 
product = {'month' : [1,2,3,4,5,6,7,8,9,10,11,12],'demand':[290,260,288,300,310,303,329,340,316,330,308,310]}
df = pd.DataFrame(product)
df.head()
 

Code aus diesem Tutorial online ausführen und bearbeiten

Code ausführen
  month demand
0 1 290
1 2 260
2 3 288
3 4 300
4 5 310

Lass uns den SMA für eine Fenstergröße von 3 berechnen. Das bedeutet, du nimmst jeweils drei Werte, um den gleitenden Durchschnitt zu bilden, und bei jedem neuen Wert fällt der älteste weg.

Dafür verwendest du in pandas die Funktion iloc. Da du die Spalte demand brauchst, fixierst du deren Position in iloc, während die Zeile eine Variable i ist, die du iterierst, bis du das Ende des DataFrames erreichst.

for i in range(0,df.shape[0]-2):
    df.loc[df.index[i+2],'SMA_3'] = np.round(((df.iloc[i,1]+ df.iloc[i+1,1] +df.iloc[i+2,1])/3),1)
  month demand SMA_3
0 1 290 NaN
1 2 260 NaN
2 3 288 279.3
3 4 300 282.7
4 5 310 299.3

Zur Plausibilitätsprüfung nutzen wir zusätzlich die eingebaute rolling-Funktion von pandas und prüfen, ob sie mit unserem eigenen Python-SMA übereinstimmt.

df['pandas_SMA_3'] = df.iloc[:,1].rolling(window=3).mean()
df.head()
  month demand SMA_3 pandas_SMA_3
0 1 290 NaN NaN
1 2 260 NaN NaN
2 3 288 279.3 279.333333
3 4 300 282.7 282.666667
4 5 310 299.3 299.333333

Super. Wie du siehst, stimmen eigener und pandas-basierter gleitender Durchschnitt exakt überein. Deine SMA-Implementierung passt.

Berechnen wir schnell auch den einfachen gleitenden Durchschnitt für eine window_size von 4.

for i in range(0,df.shape[0]-3):
    df.loc[df.index[i+3],'SMA_4'] = np.round(((df.iloc[i,1]+ df.iloc[i+1,1] +df.iloc[i+2,1]+df.iloc[i+3,1])/4),1)
df.head()
  month demand SMA_3 pandas_SMA_3 SMA_4
0 1 290 NaN NaN NaN
1 2 260 NaN NaN NaN
2 3 288 279.3 279.333333 NaN
3 4 300 282.7 282.666667 284.5
4 5 310 299.3 299.333333 289.5
df['pandas_SMA_4'] = df.iloc[:,1].rolling(window=4).mean()
df.head()
  month demand SMA_3 pandas_SMA_3 SMA_4 pandas_SMA_4
0 1 290 NaN NaN NaN NaN
1 2 260 NaN NaN NaN NaN
2 3 288 279.3 279.333333 NaN NaN
3 4 300 282.7 282.666667 284.5 284.5
4 5 310 299.3 299.333333 289.5 289.5

Jetzt visualisierst du die berechneten gleitenden Durchschnitte.

import matplotlib.pyplot as plt
%matplotlib inline
plt.figure(figsize=[15,10])
plt.grid(True)
plt.plot(df['demand'],label='data')
plt.plot(df['SMA_3'],label='SMA 3 Months')
plt.plot(df['SMA_4'],label='SMA 4 Months')
plt.legend(loc=2)
<matplotlib.legend.Legend at 0x11fe15080>
calculated moving averages line graph

Kumulativer gleitender Durchschnitt

Ich denke, wir sind bereit für einen echten Datensatz.

Für den kumulativen gleitenden Durchschnitt verwenden wir ein air quality dataset, das du unter diesem Link herunterladen kannst.

df = pd.read_csv("AirQualityUCI/AirQualityUCI.csv", sep = ";", decimal = ",")
df = df.iloc[ : , 0:14]
df.head()
  Date Time CO(GT) PT08.S1(CO) NMHC(GT) C6H6(GT) PT08.S2(NMHC) NOx(GT) PT08.S3(NOx) NO2(GT) PT08.S4(NO2) PT08.S5(O3) T RH
0 10/03/2004 18.00.00 2.6 1360.0 150.0 11.9 1046.0 166.0 1056.0 113.0 1692.0 1268.0 13.6 48.9
1 10/03/2004 19.00.00 2.0 1292.0 112.0 9.4 955.0 103.0 1174.0 92.0 1559.0 972.0 13.3 47.7
2 10/03/2004 20.00.00 2.2 1402.0 88.0 9.0 939.0 131.0 1140.0 114.0 1555.0 1074.0 11.9 54.0
3 10/03/2004 21.00.00 2.2 1376.0 80.0 9.2 948.0 172.0 1092.0 122.0 1584.0 1203.0 11.0 60.0
4 10/03/2004 22.00.00 1.6 1272.0 51.0 6.5 836.0 131.0 1205.0 116.0 1490.0 1110.0 11.2 59.6

Vorverarbeitung ist ein entscheidender Schritt, wenn du mit Daten arbeitest. Für numerische Daten gehört das Prüfen auf NaN (Null)-Werte zu den gängigen Schritten. Falls es NaN-Werte gibt, kannst du sie z. B. durch 0, den Durchschnitt, vorherige oder nachfolgende Werte ersetzen oder die Zeilen sogar löschen. Ersetzen ist meist besser als löschen. Da dieser Datensatz jedoch nur wenige NULL-Werte hat, beeinträchtigt das Löschen die Kontinuität der Reihe nicht.

df.isna().sum()
Date             114
Time             114
CO(GT)           114
PT08.S1(CO)      114
NMHC(GT)         114
C6H6(GT)         114
PT08.S2(NMHC)    114
NOx(GT)          114
PT08.S3(NOx)     114
NO2(GT)          114
PT08.S4(NO2)     114
PT08.S5(O3)      114
T                114
RH               114
dtype: int64

Aus der Ausgabe oben siehst du, dass es rund 114 NaN-Werte über alle Spalten gibt. Sie liegen jedoch alle am Ende der Zeitreihe, daher können wir sie schnell entfernen.

df.dropna(inplace=True)
df.isna().sum()
Date             0
Time             0
CO(GT)           0
PT08.S1(CO)      0
NMHC(GT)         0
C6H6(GT)         0
PT08.S2(NMHC)    0
NOx(GT)          0
PT08.S3(NOx)     0
NO2(GT)          0
PT08.S4(NO2)     0
PT08.S5(O3)      0
T                0
RH               0
dtype: int64

Wir wenden den kumulativen gleitenden Durchschnitt auf die Temperaturspalte (T) an. Trennen wir diese Spalte schnell vom restlichen Datensatz ab.

df_T = pd.DataFrame(df.iloc[:,-2])
df_T.head()
  T
0 13.6
1 13.3
2 11.9
3 11.0
4 11.2

Jetzt verwenden wir die pandas-Methode expanding, um den kumulativen Durchschnitt der obigen Daten zu berechnen. Zur Erinnerung: Anders als der einfache gleitende Durchschnitt berücksichtigt der kumulative gleitende Durchschnitt alle vorangegangenen Werte.

df_T['CMA_4'] = df_T.expanding(min_periods=4).mean()
df_T.head(10)
  T CMA_4
0 13.6 NaN
1 13.3 NaN
2 11.9 NaN
3 11.0 12.450000
4 11.2 12.200000
5 11.2 12.033333
6 11.3 11.928571
7 10.7 11.775000
8 10.7 11.655556
9 10.3 11.520000

Zeitreihendaten werden gegen die Zeit aufgetragen. Kombinieren wir also die Spalten Datum und Uhrzeit und wandeln sie in ein Datetime-Objekt um. Dafür nutzt du das Python-Modul datetime (Quelle: Time Series Tutorial).

import datetime

df['DateTime'] = (df.Date) + ' ' + (df.Time)
df.DateTime = df.DateTime.apply(lambda x: datetime.datetime.strptime(x, '%d/%m/%Y %H.%M.%S'))

Ändern wir nun den Index des temperature-DataFrames auf Datetime.

df_T.index = df.DateTime

Jetzt plotten wir die tatsächliche Temperatur und den kumulativen gleitenden Durchschnitt über die Zeit.

plt.figure(figsize=[15,10])
plt.grid(True)
plt.plot(df_T['T'],label='temperature')
plt.plot(df_T['CMA_4'],label='CMA_4')
plt.legend(loc=2)
<matplotlib.legend.Legend at 0x1210a2d30>
time series data graph

Exponentieller gleitender Durchschnitt

df_T['EMA'] = df_T.iloc[:,0].ewm(span=40,adjust=False).mean()
df_T.head()
  T CMA_4 EMA
DateTime      
2004-03-10 18:00:00 13.6 NaN 13.600000
2004-03-10 19:00:00 13.3 NaN 13.585366
2004-03-10 20:00:00 11.9 NaN 13.503153
2004-03-10 21:00:00 11.0 12.45 13.381048
2004-03-10 22:00:00 11.2 12.20 13.274655
plt.figure(figsize=[15,10])
plt.grid(True)
plt.plot(df_T['T'],label='temperature')
plt.plot(df_T['CMA_4'],label='CMA_4')
plt.plot(df_T['EMA'],label='EMA')
plt.legend(loc=2)
<matplotlib.legend.Legend at 0x14b2a41d0>
time series data graph 2

Wow! Wie du im obigen Diagramm siehst, bildet der Exponentielle gleitende Durchschnitt (EMA) das Muster der Daten hervorragend ab, während der Kumulative gleitende Durchschnitt (CMA) deutlich hinterherhinkt.

Geh noch weiter!

Glückwunsch, du hast das Tutorial abgeschlossen.

Dieses Tutorial war ein guter Einstieg, um die gleitenden Durchschnitte deiner Daten zu berechnen und sinnvoll zu interpretieren.

Versuche, den kumulativen und den exponentiellen gleitenden Durchschnitt in Python ohne die pandas-Bibliothek zu programmieren. Das gibt dir ein tieferes Verständnis dafür, wie sie berechnet werden und worin sie sich unterscheiden.

Es gibt noch viel zu experimentieren. Berechne zum Beispiel die partielle Autokorrelation zwischen den Eingangsdaten und dem gleitenden Durchschnitt und suche nach Zusammenhängen.

Wenn du mehr über DataFrames in pandas lernen möchtest, schau dir den interaktiven Kurs pandas Foundations von DataCamp an.

Referenzen:

Stell gern deine Fragen zu diesem Tutorial unten in den Kommentaren.

Themen
Python
Datenvisualisierung
Datenanalyse

Verwandte Kurse

Kurs

Python für Fortgeschrittene

4 Std.
1.4M
Erweitere deine Data-Science-Fähigkeiten und lerne, wie du mit Matplotlib Visualisierungen erstellst und DataFrames mit pandas bearbeitest.
Details anzeigenRight Arrow
Kurs Starten
Mehr anzeigenRight Arrow