Skip to main content

Python으로 시계열 데이터 다루기

Python으로 시계열 데이터 다루기

  • 주요 개념:
    • datetime
    • resample
    • rolling
    • groupby

하나의 날짜/시간

  • 날짜/시간 자료형으로 변환
    import pandas as pd
    date = pd.to_datetime('2025-06-20')
  • date.year : 년
  • date.month : 월
  • date.week : 주
  • date.day : 일
  • date.weekday() : 요일(0=월, 1=화, 2=수, 3=목, 4=금, 5=토, 6=일)
  • date.hour : 시
  • date.minute : 분
  • date.second : 초

고정된 간격의 기간 더하기

delta = pd.Timedelta(1, 'D')
date + delta
WDhms
  • 년(Y)과 월(M)은 간격이 일정하지 않아 지원이 안됨

달력 기준의 날짜 계산

date + pd.DateOffset(years=1) # 1년 후
date + pd.DateOffset(months=3) # 3개월 후
date + pd.DateOffset(weekday=0) # 다음 월요일

알파벳 주가 데이터

df = pd.read_excel('GOOG.xlsx')
df.head()
  • 문자열을 날짜 시간 형식으로 변환
    df.Date = pd.to_datetime(df.Date)
  • Date 컬럼을 인덱스(행 이름)으로 변환
    df.set_index('Date', inplace=True)

날짜로 인덱싱

  • 2014년 3월 31일 데이터
    df.loc['2014-03-31']
  • 일정 기간 데이터
    df.loc['2014-03-31':'2014-04-02']
  • 특정 시점의 데이터
    df.loc['2014-05'] # 2014년 5월
    df.loc['2016'] # 2016년

정렬 & 시각화

  • 인덱스를 순서대로 정렬
    df.sort_index(inplace=True)
  • 시각화
    df.Price.plot()

변화량 구하기

  • 전일과 차이 구하기
    df.Price.diff()
  • 전일과 차이의 비율 구하기
    df.Price.pct_change()
    시각화 하려면 끝에 .plot()

일정 간격으로 데이터 뽑기

  • 매월 말일 주가
    df.Price.asfreq('ME')
  • Y(연), Q(분기), M(월), W(주), D(일)
  • B를 붙이면 주말 제외(영업일)
  • S를 붙이면 기초를 뜻함: YS(연초), QS(분기초) 등
  • E를 붙이면 기말을 뜻함: YE(연말), QE(분기말) 등
  • 분기에 기준 월을 붙일 수 있음: QS-FEB(2월 1일부터 3개월 간격)
  • 주에 기준 요일을 붙일 수 있음: W-WED(매주 수요일)

그래프 겹쳐 그리기

  • .plot을 같은 셀에서 실행하면 그래프가 겹쳐서 그려짐
    df.Price.plot(alpha=0.3)
    df.Price.asfreq('BA').plot(color='red', style='o-')
  • 그래프 옵션
    • alpha: 불투명도. 0은 완전 투명, 1은 완전 불투명.
    • color: 색상
    • style: 선 모양(o- 굵은 점과 실선, - 실선, -- 대시, : 점선, -. 대시와 점선)

빈 데이터 채우기

  • 2016-12-31의 전후 날짜 데이터
    df.Price['2016-12-30':'2017-01-03']
  • 2016년 12월 31일~2017년 1월 2일까지 비어있음
  • 해당 날짜의 데이터가 비어있을 경우 이전(forward)의 데이터로 채우기
    df.Price.asfreq('YE', method='ffill')
    • 2016-12-30의 771.82로 2016-12-31을 채움
  • 해당 날짜의 데이터가 비어있을 경우 이후(back)의 데이터로 채우기
    df.Price.asfreq('YE', method='bfill')
    • 2017-01-03의 786.14로 2016-12-31을 채움

리샘플 resample

  • 특정 시점 간격으로 데이터를 종합
  • 아래는 가격을 매년 초(YS)를 기준으로 잘라, 연 평균 가격을 계산
    df.Price.resample('YS').mean()
  • 적용할 수 있는 함수들:
    • sum, mean, std, sem, max, min, median, first, last, ohlc
    • ohlc: 시초가, 고가, 저가, 종가
  • 옵션
    • rule: 원하는 리샘플링 빈도(예: YS)
    • fill_method: 결측값을 채우는 방법(ffill, bfill).
      • 기본값: 채우지 않음.
    • closed: 구간의 왼쪽 left과 오른쪽 right 중 어느 쪽을 포함하는가

이동 평균

  • rolling을 이용해서 매 365일 간격의 데이터를 묶음
    rolling = df.Price.rolling(365, center=True)
  • 각 묶음별로 평균
    rolling.mean().plot()

리샘플과 이동평균의 차이

  • 리샘플 resample은 일정 간격으로 구분(2019년 평균, 2020년 평균 등)
  • 이동평균 rolling은 모든 날짜를 기준으로 전후 365일의 평균

퀴즈