Pandas & NumPy Academy · Lekcja

Wykładniczo ważona średnia krocząca

Stosuj wygładzanie wykładnicze, aby nadać nowszym wartościom większą wagę, za pomocą ewm(span=), będącego standardową techniką w analizie finansowej.

Lekcja 3 z 413 kroki

Wykładniczo ważona średnia krocząca to bezpłatna lekcja Pandas & NumPy Academy na CoddyKit. To lekcja 3 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Pandas & NumPy Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Pandas & NumPy Academy zawiera 4 lekcji w sumie.

Problem z prostymi średnimi kroczącymi

Prosta średnia krocząca traktuje wszystkie n obserwacji w oknie jednakowo — cena sprzed 30 dni ma taki sam wpływ jak cena z wczoraj. Jednak przy przewidywaniu wartości w najbliższej przyszłości nowsze obserwacje dostarczają więcej informacji niż starsze. Wykładniczo ważona średnia krocząca (EWMA) rozwiązuje ten problem, przypisując wykładniczo malejące wagi starszym obserwacjom: wczorajsza ma największą wagę, obserwacja sprzed dwóch dni nieco mniejszą i tak dalej aż do początku szeregu.

import pandas as pd
import numpy as np

np.random.seed(42)
prices = pd.Series(
    100 + np.cumsum(np.random.normal(0.5, 2, 30)),
    index=pd.date_range('2024-01-01', periods=30)
)

df = pd.DataFrame({'price': prices})
df['SMA_7'] = df['price'].rolling(7).mean()
df['EWM_span7'] = df['price'].ewm(span=7).mean()
print(df.tail(5).round(2))

Jak działa ważenie EWMA

EWMA oblicza każdą wartość jako ważoną kombinację bieżącej obserwacji i poprzedniej wartości EWMA: EWM_t = alpha * x_t + (1 - alpha) * EWM_{t-1}. Alpha (współczynnik wygładzania) określa szybkość zanikania wag — duża wartość alpha (bliska 1) szybko reaguje na ostatnie zmiany (mniejsze wygładzanie), a mała wartość alpha (bliska 0) reaguje powoli (większe wygładzanie). Wagi tworzą szereg geometryczny: najnowsza wartość ma wagę alpha, poprzednia ma wagę alpha*(1-alpha) i tak dalej.

import numpy as np

# Manually show EWMA weights
alpha = 0.3
n_points = 8
weights = [alpha * (1 - alpha)**i for i in range(n_points)]

print(f'Alpha = {alpha}')
print(f'Weights (most recent first):')
for i, w in enumerate(weights):
    print(f'  t-{i}: {w:.4f}')
print(f'Sum of shown weights: {sum(weights):.4f} (converges to 1.0)')

Metoda ewm() i parametr span

Pandas implementuje EWMA za pomocą Series.ewm(). Najbardziej intuicyjnym parametrem jest span, analogiczny do okna prostej średniej kroczącej: alpha = 2 / (span + 1). Wartość span równa 10 w przybliżeniu odpowiada 10-okresowej SMA, ale zamiast równych wag wykorzystuje wagi malejące wykładniczo. Należy użyć ewm(span=n).mean(), aby uzyskać EWMA, oraz ewm(span=n).std() do obliczania zmienności ważonej wykładniczo.

import pandas as pd
import numpy as np

np.random.seed(0)
data = pd.Series(
    np.random.normal(100, 10, 50),
    index=pd.date_range('2024-01-01', periods=50)
)

df = pd.DataFrame({'value': data})
df['EWM_3'] = df['value'].ewm(span=3).mean()
df['EWM_10'] = df['value'].ewm(span=10).mean()
df['EWM_20'] = df['value'].ewm(span=20).mean()

print('Alpha values:')
for span in [3, 10, 20]:
    alpha = 2 / (span + 1)
    print(f'  span={span} → alpha={alpha:.3f}')
print(df.tail(5).round(2))

Parametr halflife

Parametr halflife określa, ile okresów potrzeba, aby waga zmniejszyła się o połowę. Jeśli halflife=5, wartość sprzed 5 okresów ma połowę wagi bieżącej wartości. Zależność można zapisać następująco: alpha = 1 - exp(log(0.5) / halflife). Parametr halflife jest często bardziej intuicyjny niż span lub alpha, ponieważ bezpośrednio wyraża „pamięć” średniej w kategoriach biznesowych — na przykład: „ceny sprzed 2 tygodni powinny mieć połowę wpływu ceny z dzisiaj”.

import pandas as pd
import numpy as np

np.random.seed(5)
prices = pd.Series(
    100 + np.cumsum(np.random.normal(0, 2, 30)),
    index=pd.date_range('2024-01-01', periods=30)
)

df = pd.DataFrame({'price': prices})
# halflife=5: weight halves every 5 days
df['EWM_hl5'] = df['price'].ewm(halflife=5).mean()
# halflife=14: weight halves every 14 days (longer memory)
df['EWM_hl14'] = df['price'].ewm(halflife=14).mean()

print(df.tail(5).round(2))

Parametr alpha bezpośrednio

Współczynnik wygładzania można również ustawić bezpośrednio za pomocą ewm(alpha=). Alpha musi należeć do przedziału od 0 do 1 (bez wartości krańcowych). Wysoka wartość alpha, na przykład 0.8, zapewnia bardzo niewielkie wygładzanie — EWMA dokładnie śledzi surowy sygnał. Niska wartość alpha, na przykład 0.1, zapewnia silne wygładzanie — EWMA zmienia się powoli i reaguje z opóźnieniem na nagłe przesunięcia. Wybór właściwej wartości alpha zależy od kompromisu między responsywnością (szybkim wykrywaniem rzeczywistych zmian trendu) a stabilnością (ignorowaniem losowego szumu).

import pandas as pd
import numpy as np

np.random.seed(3)
data = pd.Series(
    [100]*20 + [120]*20,  # sudden level shift at row 20
    dtype=float
) + np.random.normal(0, 2, 40)

df = pd.DataFrame({'signal': data})
df['alpha_0.1'] = df['signal'].ewm(alpha=0.1).mean()  # slow
df['alpha_0.5'] = df['signal'].ewm(alpha=0.5).mean()  # medium
df['alpha_0.9'] = df['signal'].ewm(alpha=0.9).mean()  # fast

print('After the level shift (rows 20-25):')
print(df.iloc[18:26].round(2))

EWMA dla zmienności: ewm().std()

ewm(span=).std() oblicza wykładniczo ważone odchylenie standardowe. Stanowi ono podstawę modelu zmienności EWMA używanego w zarządzaniu ryzykiem finansowym (znanego również jako model RiskMetrics ze współczynnikiem zaniku lambda=0.94). Zmienność ważona wykładniczo szybciej reaguje na skoki zmienności niż proste kroczące odchylenie standardowe, ponieważ nadaje większą wagę nowszym obserwacjom o dużej wariancji.

import pandas as pd
import numpy as np

np.random.seed(42)
# Simulate returns: quiet period then volatile period
returns = pd.Series(
    np.concatenate([
        np.random.normal(0, 0.01, 60),
        np.random.normal(0, 0.04, 60)  # 4x more volatile
    ]),
    index=pd.date_range('2024-01-01', periods=120)
)

df = pd.DataFrame({'returns': returns})
df['rolling_vol'] = df['returns'].rolling(20).std()
df['ewm_vol'] = df['returns'].ewm(span=20).std()

print('Volatility comparison (transition at row 60):')
print(df.iloc[58:65].round(5))

MACD: łączenie dwóch wartości EWMA

MACD (Moving Average Convergence Divergence) to klasyczny wskaźnik finansowy zbudowany na podstawie dwóch wartości EWMA. Jest różnicą między szybką wartością EWMA (z krótkim span) a wolną wartością EWMA (z długim span) dla ceny. Gdy MACD przekracza zero od dołu, sygnalizuje to potencjalny wzrostowy impet (sygnał kupna); przejście od góry sygnalizuje impet spadkowy. MACD jest doskonałym przykładem zastosowania dwóch wartości EWMA do wyprowadzenia pochodnego wskaźnika.

import pandas as pd
import numpy as np

np.random.seed(7)
prices = pd.Series(
    100 + np.cumsum(np.random.normal(0.3, 2, 100)),
    index=pd.date_range('2024-01-01', periods=100)
)

df = pd.DataFrame({'price': prices})
df['EMA_12'] = df['price'].ewm(span=12).mean()  # fast
df['EMA_26'] = df['price'].ewm(span=26).mean()  # slow
df['MACD'] = df['EMA_12'] - df['EMA_26']
df['Signal'] = df['MACD'].ewm(span=9).mean()   # signal line

print('MACD values (last 8 rows):')
print(df[['price', 'MACD', 'Signal']].tail(8).round(2))

EWMA z halflife zależnym od czasu

Pandas 1.1+ obsługuje określanie halflife, span i com jako przesunięć czasowych (np. halflife='7D') podczas pracy z DatetimeIndex. Umożliwia to poprawne obliczanie EWMA dla nieregularnych szeregów czasowych — na przykład gdy dane godzinowe zawierają przerwy w weekendy, halflife równe '7D' oznacza, że waga rzeczywiście zmniejsza się o połowę co 7 dni kalendarzowych, niezależnie od liczby wierszy w tym okresie.

import pandas as pd
import numpy as np

np.random.seed(0)
# Business-day data (no weekends)
biz_dates = pd.bdate_range('2024-01-01', periods=20)
prices = pd.Series(100 + np.cumsum(np.random.randn(20)), index=biz_dates)

# halflife as a time offset (7 calendar days)
ewm_7d = prices.ewm(halflife='7D', times=biz_dates).mean()
# halflife as row count (7 rows)
ewm_7rows = prices.ewm(halflife=7).mean()

df = pd.DataFrame({'price': prices, 'hl_7D': ewm_7d, 'hl_7rows': ewm_7rows})
print(df.round(2))

Wybór między EWMA, rolling i expanding

Podsumowanie zastosowań poszczególnych metod:

  • Rolling(n).mean(): wszystkie n najnowszych obserwacji ma taką samą wagę — dobre rozwiązanie w przypadku prostych metryk opóźnionych oraz gdy wszystkie ostatnie okresy są jednakowo istotne.
  • ewm(span=n).mean(): wagi maleją wykładniczo — najlepsze rozwiązanie, gdy potrzebne jest wygładzanie silniej reagujące na ostatnie zmiany; metoda jest często używana w finansach i przetwarzaniu sygnałów.
  • expanding().mean(): wszystkie dane historyczne mają taką samą wagę — najlepsze rozwiązanie dla wartości YTD lub statystyk dla całej historii, w przypadku których nie można zapominać o starych danych.

Wizualizacja EWMA i SMA

Wykres szeregu czasowego przedstawiający jednocześnie EWMA i SMA uwidacznia różnicę w ich reaktywności. EWMA szybciej reaguje na nagłe zmiany poziomu, ponieważ nie „zapomniała” wszystkich wcześniejszych obserwacji — EWMA o krótkim rozpięciu zmieni kierunek szybciej niż SMA z takim samym nominalnym oknem. Dzięki temu EWMA jest lepszym wyborem w zastosowaniach prognostycznych, w których szybkie uchwycenie kierunku trendu jest ważniejsze niż maksymalne ograniczenie szumu.

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

np.random.seed(42)
prices = pd.Series(
    np.concatenate([
        100 + np.cumsum(np.random.normal(0.3, 1.5, 50)),
        130 + np.cumsum(np.random.normal(-0.3, 1.5, 50))
    ]),
    index=pd.date_range('2024-01-01', periods=100)
)

df = pd.DataFrame({'price': prices})
df['SMA_10'] = df['price'].rolling(10).mean()
df['EWMA_10'] = df['price'].ewm(span=10).mean()

df.plot(figsize=(12, 5), title='SMA vs EWMA — EWMA reacts faster to trend reversals')
plt.ylabel('Price')
plt.axvline(x=df.index[50], color='red', linestyle='--', label='Trend change')
plt.legend()
plt.show()

EWMA w zastosowaniach biznesowych

Poza finansami EWMA jest szeroko stosowana w analityce produktu i operacjach: do wygładzania wartości klienta w całym okresie jego życia (nowsze zachowanie lepiej przewiduje przyszłe wydatki niż stare), monitorowania opóźnień serwera (wykładniczo wygładzona miara opóźnienia szybciej sygnalizuje fałszywe alarmy niż średnia krocząca) oraz prognozowania popytu na zapasy (sprzedaż z ostatnich tygodni powinna mieć większą wagę niż dane sprzed sześciu miesięcy). Uniwersalna zasada brzmi: wszędzie tam, gdzie liczy się aktualność danych, EWMA przewyższa zwykłe uśrednianie.

Szybkie sprawdzenie

Sprawdź swoją wiedzę na temat wykładniczo ważonych średnich kroczących z tego modułu.

Podsumowanie modułu

W tym module nauczyli się Państwo, że: ewm(span=) stosuje wykładniczo malejące wagi, dzięki czemu nowsze obserwacje mają większe znaczenie, alpha steruje reaktywnością (wysoka = szybka reakcja, niska = większe wygładzenie), a parametr halflife wyraża pamięć w kategoriach zrozumiałych biznesowo. EWMA przewyższa SMA, gdy ważne jest szybkie wykrywanie odwrócenia trendu. Następnie omówimy obliczanie rang i percentyli w grupach za pomocą groupby().rank() i pd.qcut.

Bezpłatny start

Ucz się Python dzięki korepetycjom AI — za darmo

Pisz i uruchamiaj kod w przeglądarce, otrzymuj natychmiastową pomoc od korepetytora AI dostępnego 24/7 i kontynuuj naukę w sieci lub w aplikacji.

Kursy
30
Lekcje
120

Często zadawane pytania

Czy lekcja „Wykładniczo ważona średnia krocząca” jest bezpłatna?

Tak — pełny tekst „Wykładniczo ważona średnia krocząca” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Pandas & NumPy Academy, przejdź na CoddyKit PRO. Kurs Pandas & NumPy Academy zawiera 4 lekcji w sumie.

Co nauczysz się w „Wykładniczo ważona średnia krocząca”?

Stosuj wygładzanie wykładnicze, aby nadać nowszym wartościom większą wagę, za pomocą ewm(span=), będącego standardową techniką w analizie finansowej. Ćwiczysz Pandas & NumPy Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.

Czy potrzebuję doświadczenia, aby zacząć Pandas & NumPy Academy?

Nie wymagamy żadnego doświadczenia. Pandas & NumPy Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 3 z 4.

Ile czasu zajmuje lekcja „Wykładniczo ważona średnia krocząca”?

Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.

Czy mogę pisać i uruchamiać kod w tej lekcji Pandas & NumPy Academy?

Tak. Każda lekcja Pandas & NumPy Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.

Wszystkie lekcje w tym kursie

  1. Okna kroczące
  2. Okna rozszerzające
  3. Wykładniczo ważona średnia krocząca
  4. Rangi i percentyle w grupach
← Powrót do Pandas & NumPy Academy