Skip to content

Pandas Rolling Window: Rolling, Expanding, and EWM

Updated on

이동 평균(moving average)과 smoothed signal은 시계열 분석의 핵심이지만, 많은 팀이 window alignment, 결측값 처리, 느린 Python loop 때문에 어려움을 겪습니다.

  • Problem: rolling 통계를 직접 계산하면 오류가 많고 timestamp와 맞지 않게 정렬되는 경우가 많습니다.
  • Agitate: loop와 임시 shift 조합은 off-by-one 오류, 초기 구간의 gap, 느린 notebook을 초래합니다.
  • Solution: rolling, expanding, ewm을 올바른 window 정의(min_periods, time-based windows, center, adjust)와 함께 사용해 정확하고 빠르며 vectorized된 결과를 얻을 수 있습니다.

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)


Quick Reference

Window typeBest forKey parameters
rolling이동 평균, 변동성, 커스텀 window 함수window=3 (또는 "7D"), min_periods, center, win_type, on
expanding시작점부터의 누적 통계min_periods
ewm지수 가중 평활 또는 가중 metricspan, alpha, halflife, adjust, times

Sample Data

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

Rolling Windows (Fixed and Time-Based)

Fixed-size windows

sales["rev_ma3"] = (
    sales["revenue"]
    .rolling(window=3, min_periods=2)
    .mean()
)
  • min_periods는 결과가 언제부터 나오기 시작할지를 제어하며, 최소 개수가 충족될 때까지 초기 행은 NaN으로 남습니다.
  • center=True를 사용하면 통계를 window의 중앙에 정렬할 수 있어 시각화할 때 유용합니다.

datetime index 또는 on= 컬럼을 사용하는 time-based windows

sales_reset = sales.reset_index()
sales_reset["rev_7d_mean"] = (
    sales_reset.rolling("7D", on="date")["revenue"].mean()
)
  • 불규칙한 샘플링에는 "7D", "48H" 같은 duration string을 사용합니다. pandas는 고정된 row 수 대신 lookback horizon 안에 포함되는 행들을 선택합니다.
  • 경계 포함 여부를 조정하려면 closed="left" 또는 "right"를 사용합니다.

Custom window functions

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

raw=True로 설정하면 apply 내부에서 NumPy array로 작업할 수 있어 속도가 빨라집니다.


Expanding Windows (Cumulative)

sales["rev_cum_mean"] = sales["revenue"].expanding(min_periods=2).mean()
  • expanding은 각 관측치가 그 시점까지의 모든 과거 데이터를 볼 수 있어야 할 때(누적 평균, 누적 비율 등)에 사용합니다.
  • shift()와 결합해 최신 값과 과거 평균을 비교할 수 있습니다.

Exponential Weighted Windows

sales["rev_ewm_span4"] = sales["revenue"].ewm(span=4, adjust=False).mean()
  • adjust=False는 analytics dashboard에서 흔히 쓰는 smoothing과 유사한 재귀식을 사용합니다.
  • halflife는 직관적인 decay 설정을 제공합니다: ewm(halflife=3)는 3 period마다 가중치를 절반으로 줄입니다.
  • 불규칙한 timestamp에는 times="date"(또는 index 설정)를 사용해 row 개수 대신 실제 시간 간격에 따라 가중치를 줄 수 있습니다.

Choosing the Right Window (Cheat Sheet)

GoalRecommended methodNotes
단기 노이즈 완화작은 windowcenter=True를 사용한 rollingnumeric column에서 동작; 초기 구간도 보고 싶다면 min_periods를 1 이상으로 설정
시작점부터의 누적 합계 또는 평균expanding고정 window 없음; 누적형 KPI에 적합
오래된 관측치의 영향 감소ewm(span=...)큰 rolling window 대신 momentum 류 signal에 더 적합
불규칙한 timestamprolling("7D", on="date") 같은 time-based rolling 또는 ewm(..., times="date")샘플링이 조밀한 날에 생기는 bias를 피할 수 있음
Feature 생성rolling().agg(["mean","std","min","max"])여러 aggregation을 한 번에 계산해 feature set을 빠르게 구성

Performance and Correctness Tips

  • time-based window를 많이 쓸 때는 datetime 컬럼을 datetime64[ns]로 유지하고 index로 설정하는 것이 좋습니다.
  • 속도를 위해 Python apply보다는 mean, std, sum, count 같은 built-in aggregation을 우선 사용합니다.
  • 미래 정보를 미리 보는 bias를 피하려면 supervised learning feature를 만들 때 rolling 전에 shift()를 적용합니다.
  • 원본 데이터가 불규칙하다면 resample로 빈도를 정규화한 뒤 rolling을 적용하는 것을 고려하세요.

rolling, expanding, ewm window만으로도 대부분의 smoothing과 feature engineering 요구를 loop 없이 해결할 수 있습니다. 이를 pandas-to-datetime, pandas-resample과 함께 사용해 깨끗한 time axis를 구성하면, 차트나 모델에 바로 쓸 수 있는 빠르고 신뢰할 수 있는 metric을 얻을 수 있습니다.