0Pricing
Pandas & NumPy Academy · 강의

이동 창

rolling(n).mean() 및 관련 메서드로 고정된 행 개수에 대한 이동 평균, 합계, 표준 편차를 계산합니다.

이동 창은(는) CoddyKit의 무료 Pandas & NumPy Academy 강의입니다. 이것은 4개 중 1번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 Pandas & NumPy Academy 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. Pandas & NumPy Academy 강의에는 총 4개의 강의가 포함되어 있습니다.

이동 윈도란 무엇인가요

이동 윈도(슬라이딩 윈도 또는 이동 윈도라고도 함)는 고정된 크기의 연속된 행 구간을 한 번에 한 행씩 앞으로 이동하면서 해당 구간의 통계량을 계산합니다. 예를 들어 7일 이동 평균은 각 날짜의 값을 해당 날짜와 이전 6일의 평균으로 바꿉니다. 이동 윈도는 금융의 이동 평균, 잡음이 있는 센서 데이터의 평활화, 비즈니스 대시보드의 최근 지표를 계산하는 데 기반이 됩니다.

import pandas as pd
import numpy as np

# Simple example: 3-day rolling mean
data = pd.Series([10, 12, 15, 11, 9, 13, 16, 14, 12, 18],
                 index=pd.date_range('2024-01-01', periods=10))

rolling_mean = data.rolling(window=3).mean()
print('Original:')
print(data.values)
print('\n3-day rolling mean:')
print(rolling_mean.values.round(2))

rolling() 메서드와 window 매개변수

Series.rolling(window=n)은 Rolling 객체를 반환합니다. window 매개변수는 슬라이딩 윈도의 크기를 행 수(정수 윈도인 경우) 또는 '7D'와 같은 시간 오프셋(시간 인덱스를 사용하는 Series인 경우)으로 지정합니다. 이동 객체를 만든 후에는 집계 메서드를 연결하여 사용할 수 있습니다: .mean(), .sum(), .std(), .min(), .max() 또는 .apply(func). 윈도를 채우기에 앞선 행이 충분하지 않으므로 처음 window-1개 행은 항상 NaN이 됩니다.

import pandas as pd
import numpy as np

prices = pd.Series(
    [100, 102, 98, 105, 110, 108, 115, 112, 120, 118],
    index=pd.date_range('2024-01-01', periods=10),
    name='price'
)

df = pd.DataFrame({'price': prices})
df['MA3'] = df['price'].rolling(3).mean()
df['MA7'] = df['price'].rolling(7).mean()
df['std3'] = df['price'].rolling(3).std()
print(df.round(2))

min_periods 매개변수

기본적으로 rolling(n)은 윈도 안에 NaN이 아닌 값이 정확히 n개 있어야 결과를 계산합니다. min_periods 매개변수는 이 요구 사항을 낮춥니다. 예를 들어 rolling(7, min_periods=3)은 값이 3개 이상 제공되는 즉시 평균을 계산하므로 Series의 앞부분에서 더 일찍 NaN이 아닌 값을 생성합니다. 시계열의 시작 부분에서 처음 n-1개 행을 NaN으로 두는 대신 이동 평균을 구하고 싶을 때 유용합니다.

import pandas as pd
import numpy as np

prices = pd.Series([100, 102, 98, 105, 110, 108, 115],
                   index=pd.date_range('2024-01-01', periods=7))

# Default: first 6 rows are NaN
ma7_default = prices.rolling(7).mean()

# min_periods=3: compute mean once 3 values available
ma7_minperiods = prices.rolling(7, min_periods=3).mean()

df = pd.DataFrame({
    'price': prices,
    'MA7_default': ma7_default,
    'MA7_min3': ma7_minperiods
})
print(df.round(2))

누적 합계를 위한 이동 합계

rolling(n).sum()은 각 위치에서 최근 n개 행의 합계를 계산합니다. 일별 매출의 30일 이동 합계는 각 날짜의 최근 한 달 매출을 제공하므로, 매일 갱신된다는 점에서 고정된 월별 합계보다 유용합니다. 이동 합계는 소매 분석(최근 30일 매출), 웹 분석(최근 7일 활성 사용자), 금융(최근 n기간 거래량)에서 흔히 사용됩니다.

import pandas as pd
import numpy as np

np.random.seed(42)
dates = pd.date_range('2024-01-01', periods=60)
daily_sales = pd.Series(np.random.randint(100, 500, 60), index=dates, name='daily_sales')

df = pd.DataFrame({'daily_sales': daily_sales})
df['trailing_7d'] = df['daily_sales'].rolling(7).sum()
df['trailing_30d'] = df['daily_sales'].rolling(30).sum()

print(df.tail(10).round(0))

변동성 측정을 위한 이동 표준편차

금융에서 변동성은 일별 수익률의 이동 표준편차로 측정합니다. 이동 표준편차가 높으면 가격이 크게 요동한다는 뜻이고, 낮으면 가격이 안정적이라는 뜻입니다. 이 지표는 옵션 가격 결정과 포트폴리오 관리의 위험 계산에 사용됩니다. 공식은 다음과 같습니다. np.log(price/price.shift(1))로 일별 로그 수익률을 계산한 다음 rolling(window).std()를 적용합니다.

import pandas as pd
import numpy as np

np.random.seed(0)
prices = pd.Series(
    100 * np.exp(np.cumsum(np.random.normal(0.001, 0.02, 120))),
    index=pd.date_range('2024-01-01', periods=120)
)

# Daily log returns
log_returns = np.log(prices / prices.shift(1))

# 20-day rolling volatility (annualised)
volatility = log_returns.rolling(20).std() * np.sqrt(252)

print('Last 5 rows of daily volatility:')
print(volatility.tail(5).round(4))

시간 기반 이동 윈도

고정된 행 수 대신 윈도로 시간 오프셋을 지정할 수 있습니다. rolling('7D')는 '최근 7일의 달력 기간에 해당하는 데이터'를 의미합니다. 이 방식은 불규칙한 시계열(주말이나 공휴일 누락)을 자동으로 올바르게 처리합니다. 행 수 기반 윈도는 중간에 누락된 기간에 따라 포함하는 달력 시간이 달라지지만, 시간 오프셋 윈도는 항상 정확히 7일의 데이터를 포함합니다. 시간 기반 윈도를 사용하려면 Series에 DatetimeIndex가 있어야 합니다.

import pandas as pd
import numpy as np

# Business-day index (no weekends)
biz_dates = pd.bdate_range('2024-01-01', periods=15)
sales = pd.Series(np.random.randint(100, 300, 15), index=biz_dates)

# 7-calendar-day window (variable row count near weekends)
df = pd.DataFrame({'sales': sales})
df['rolling_7d'] = sales.rolling('7D').mean()

print(df.round(1))

사용자 지정 함수를 위한 이동 apply

rolling(n).apply(func)는 각 윈도를 NumPy 배열로 변환하여 사용자 지정 함수에 전달합니다. 이를 통해 기본 제공 집계로 처리할 수 없는 모든 이동 계산을 수행할 수 있습니다. 예를 들어 이동 중앙값 절대 편차, 이동 왜도 또는 이동 제1사분위수를 계산할 수 있습니다. 함수는 1차원 배열을 받아 스칼라 값을 반환해야 합니다. 참고로 apply는 벡터화할 수 없으므로 기본 제공 메서드보다 느립니다.

import pandas as pd
import numpy as np

prices = pd.Series(
    [100, 102, 98, 105, 110, 95, 115, 112, 120, 108],
    index=pd.date_range('2024-01-01', periods=10)
)

# Rolling range (max - min) over a 5-day window
def rolling_range(arr):
    return arr.max() - arr.min()

df = pd.DataFrame({'price': prices})
df['5d_range'] = prices.rolling(5).apply(rolling_range, raw=True)
print(df.round(2))

DataFrame 열에 이동 연산 적용하기

DataFrame에 직접 rolling().mean()을 적용하여 모든 숫자 열의 이동 통계량을 동시에 계산할 수 있습니다. 각 열에는 독립적으로 계산된 고유한 이동 윈도가 적용됩니다. 열을 반복 처리하지 않고 한 번의 연산으로 여러 주가 또는 여러 제품의 매출 흐름에 대한 이동 평균을 계산할 때 유용합니다.

import pandas as pd
import numpy as np

np.random.seed(42)
dates = pd.date_range('2024-01-01', periods=10)
df = pd.DataFrame({
    'AAPL': 100 + np.cumsum(np.random.randn(10)),
    'MSFT': 200 + np.cumsum(np.random.randn(10)),
    'GOOG': 150 + np.cumsum(np.random.randn(10))
}, index=dates)

# 3-day moving average of all three stocks
ma3 = df.rolling(3).mean()
print('3-day MA for all stocks:')
print(ma3.round(2))

이동 평균과 원본 데이터 결합하기

일반적인 시각화 방법은 원시 시계열과 이동 평균을 같은 축에 함께 그리는 것입니다. 이동 평균은 일별 잡음을 평활화하여 추세를 보여 주고, 원시 시계열은 변동성을 보여 줍니다. 두 값 사이의 간격은 잡음이 얼마나 많은지 나타냅니다. DataFrame에 이동 평균을 추가하는 방법은 결과를 새 열에 할당하는 것뿐입니다.

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

np.random.seed(42)
dates = pd.date_range('2024-01-01', periods=60)
sales = pd.Series(
    200 + np.cumsum(np.random.randn(60) * 10),
    index=dates, name='Daily Sales'
)

df = pd.DataFrame({'sales': sales})
df['MA7'] = df['sales'].rolling(7).mean()
df['MA30'] = df['sales'].rolling(30).mean()

df.plot(figsize=(12, 5), title='Sales with 7-day and 30-day Moving Average')
plt.ylabel('Sales')
plt.show()

중앙 이동 윈도

기본적으로 rolling은 후행 윈도(현재 행과 앞선 n-1개 행)를 사용합니다. center=True로 설정하면 현재 행이 가운데에 오고 과거와 미래의 행을 같은 수만큼 사용하는 중앙 정렬 윈도가 생성됩니다. 중앙 정렬 윈도는 더 부드러운 결과를 제공하며 미래 값이 이미 알려진 과거 데이터의 오프라인 평활화에 적합합니다. 미래 데이터가 필요하므로 실시간 예측에는 적합하지 않습니다.

import pandas as pd
import numpy as np

np.random.seed(0)
data = pd.Series(
    np.sin(np.linspace(0, 4*3.14159, 30)) + np.random.normal(0, 0.3, 30)
)

df = pd.DataFrame({'signal': data})
df['trailing_MA5'] = data.rolling(5).mean()
df['centered_MA5'] = data.rolling(5, center=True).mean()

print('Comparison (first 8 rows):')
print(df.head(8).round(3))

GroupBy 데이터의 롤링 윈도

groupby().rolling()을 사용하면 그룹별 롤링 통계를 계산할 수 있습니다. 예를 들어 제품 카테고리별 7일 롤링 매출을 계산할 때 윈도는 각 그룹의 시작 부분에서 초기화되므로 한 제품의 데이터가 다른 제품의 데이터에 섞이지 않습니다. 롤링 연산 후에는 .reset_index(level=0, drop=True)를 사용하여 인덱스에서 추가된 그룹 수준을 제거하고 결과를 원래 DataFrame에 맞출 수 있습니다.

import pandas as pd
import numpy as np

np.random.seed(42)
dates = pd.date_range('2024-01-01', periods=10)
df = pd.DataFrame({
    'date': list(dates) * 2,
    'product': ['A'] * 10 + ['B'] * 10,
    'sales': np.random.randint(50, 200, 20)
}).sort_values(['product', 'date'])

# 3-day rolling mean per product
df['rolling_mean'] = (df
    .groupby('product')['sales']
    .transform(lambda x: x.rolling(3).mean())
)
print(df.to_string(index=False))

빠른 확인

이 레슨에서 배운 롤링 윈도에 대한 이해도를 확인해 보세요.

레슨 요약

이 레슨에서는 다음을 배웠습니다. rolling(n)은 평균, 합계, std, min, max 또는 사용자 지정 함수를 계산할 수 있는 n개 행의 슬라이딩 윈도를 만들고, min_periods는 결과를 계산하는 데 필요한 최소 값의 개수를 줄이며, center=True는 오프라인 평활화를 위한 중앙 정렬 윈도를 만듭니다. 다음으로는 Series의 시작부터 누적되며 커지는 누적 통계인 확장 윈도를 살펴보겠습니다.

자주 묻는 질문

“이동 창” 강의는 무료인가요?

네 — “이동 창” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 Pandas & NumPy Academy 강의 전체를 잠금 해제할 수 있습니다. Pandas & NumPy Academy 강의에는 총 4개의 강의가 포함되어 있습니다.

“이동 창”에서 뭘 배우나요?

rolling(n).mean() 및 관련 메서드로 고정된 행 개수에 대한 이동 평균, 합계, 표준 편차를 계산합니다. 브라우저에서 직접 실행하는 실습 코드로 Pandas & NumPy Academy을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.

Pandas & NumPy Academy을(를) 시작하는 데 경험이 필요한가요?

사전 경험은 필요하지 않습니다. CoddyKit의 Pandas & NumPy Academy은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 1번째 강의입니다.

“이동 창” 강의는 얼마나 걸리나요?

대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.

이 Pandas & NumPy Academy 강의에서 코드를 작성하고 실행할 수 있나요?

네. 모든 Pandas & NumPy Academy 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.

이 강의의 모든 강의

  1. 이동 창
  2. 확장 창
  3. 지수 가중 이동 평균
  4. 그룹 내 순위와 백분위
← Pandas & NumPy Academy(으)로 돌아가기