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 type | Best for | Key parameters |
|---|---|---|
rolling | 이동 평균, 변동성, 커스텀 window 함수 | window=3 (또는 "7D"), min_periods, center, win_type, on |
expanding | 시작점부터의 누적 통계 | min_periods |
ewm | 지수 가중 평활 또는 가중 metric | span, 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)
| Goal | Recommended method | Notes |
|---|---|---|
| 단기 노이즈 완화 | 작은 window와 center=True를 사용한 rolling | numeric column에서 동작; 초기 구간도 보고 싶다면 min_periods를 1 이상으로 설정 |
| 시작점부터의 누적 합계 또는 평균 | expanding | 고정 window 없음; 누적형 KPI에 적합 |
| 오래된 관측치의 영향 감소 | ewm(span=...) | 큰 rolling window 대신 momentum 류 signal에 더 적합 |
| 불규칙한 timestamp | rolling("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을 얻을 수 있습니다.