Pandas 시계열 자료(자습용)
먼저 필요한 모듈들을 모두 불러보겠습니다.
import pandas as pd #무조건 하세요.
import numpy as np #무조건 하라고 했죠?
import fix_yahoo_finance as yf #Yhoo Finance API 사용에 필요함
from pandas_datareader import data #데이터 다운로더
from datetime import time #시계열 데이터 추출에 사용할 것임(시각)
import matplotlib.pyplot as plt #시계열 데이터 플롯
시계열 인덱스 만들기¶
시간을 인덱스로 하는 데이터를 만듭니다. 분 단위로 데이터를 추려보겠습니다. date_range()는 어디서부터 어디까지 시계열 인덱스를 생성합니다.
기호 | 설명 | 기호 | 설명 | 기호 | 설명 |
---|---|---|---|---|---|
B | 비즈니스 데이 | D | 캘린더 데이 | W | 주당 |
M | 월당 | BM | 비즈니스 월당 | Q | 분기 |
BQ | 비즈니스 분기 | A | 연간 | Y | 연간 |
H | 시 | T | 분 | S | 초 |
적절한 것을 freq로 지정하면 됩니다.
rng=pd.date_range('2012-06-01 09:30','2012-06-01 15:59',freq='T')
rng[:10]
분 단위로 인덱스가 만들어졌습니다. DatetimeIndex() 개체로 지정된 것 보입니다.
Business day기준으로 데이터를 뽑는다. BDay()는 business day로 offset 시간대를 동일하게 유지하고 비즈니스 일을 기준으로 3일을 연장해봅시다. 연장하는 방법은 offsets 처리기를 쓰면 됩니다. 비즈니스 기준 날짜를 연장하는 기능은 BDay()가 제공합니다. 데이터를 연장하여 붙이려면 append()를 하면 됩니다. Padas의 좋은 점은 Python의 list나 dict과 자유롭게 결합된다는 것입니다. 수업시간이 말씀드렸지요.
rng=rng.append([rng+pd.offsets.BDay(i) for i in range(1,4)])
이제 시계열 데이터를 만들어서 인덱스를 붙여봅시다. 그냥 1부터 숫자를 주르륵 붙이겠습니다. 데이터는 np.arange()로 생성하고 숫자는 실수(float)로 가정합시다.
ts=pd.Series(np.arange(len(rng),dtype=float),index=rng)
일부만 살펴보죠.
ts.head()
파이썬의 time()을 이용해서 시간대별 데이터를 추출하자.
시간 데이터 추출하기¶
datetime 패키지에서 가져온 time()을 써봅시다. 시, 분을 입력값으로 합니다. 10시 데이터를 뽑으려면 다음과 같이 합니다.
ts[time(10,0)]
다음과 같이 해도 결과는 같습니다.
ts.at_time(time(10,0))
두 시간 사이의 값을 구해봅시다.
ts.between_time(time(10,0),time(10,1))
이번에는 난수 순열을 만들어서 적당히 뽑은 다음 순서대로 정리해봅시다.
indexer=np.sort(np.random.permutation(len(ts))[700:])
indexer[:10]
irr_ts=ts.copy()
irr_ts[indexer]=np.nan
근사값 처리하는 모습을 이해하기 위해 일부러 값을 좀 비워봤습니다.
irr_ts.head()
irr_ts['2012-06-01 09:50':'2012-06-01 10:00']
값이 존재하지 않는 것들이 섞여 있네요. 이제 근사값을 구하는 asof와 date_range를 사용합시다.
selection=pd.date_range('2012-06-01 09:52',periods=4,freq='B')
selection
09:52데이터는 보다시피 NaN입니다.
irr_ts.asof(selection)
그러나 asof가 근사값을 구했습니다.
시계열 결합¶
data1=pd.DataFrame(np.ones((6,3),dtype=float),columns=list('abc'),index=pd.date_range('6/12/2012',periods=6))
data1.head()
data2=pd.DataFrame(np.ones((6,3),dtype=float)*2,columns=list('abc'),index=pd.date_range('6/13/2012',periods=6))
data2.head()
위 시계열 두 개를 합치는 방법은 concat을 쓰면 됩니다.
sliced=pd.concat([data1.loc[:'2012-06-14'],data2.loc['2012-06-15':]])
sliced
결합한 이후 결측 데이터가 있는 경우¶
data2=pd.DataFrame(np.ones((6,4),dtype=float)*2,columns=list('abcd'),index=pd.date_range('6/13/2012',periods=6))
data2
sliced=pd.concat([data1.loc[:'2012-06-14'],data2.loc['2012-06-15':]],sort=False)
sliced
결측 데이터인 NaN이 발생되었습니다. data1에 해당 데이터가 없기 때문입니다.
sliced_filled=sliced.combine_first(data2)
sliced_filled
combine_first()를 사용하면 입력한 것으로 NaN을 다 채웁니다. 이보다 간편한 방법은 update()를 사용하는 것입니다. 비워져 있는 것만 채우려면 overwrite=False로 합니다.
sliced.update(data2,overwrite=False)
sliced
수익률 추이 계산하기¶
수익률 추이를 계산해봅시다. Pandas나 R로는 아주 쉽게 할 수 있습니다.
한 가지 알려드릴 것은, Google과 Yahoo의 API가 변경이 되어서 교과서에 나오는 방법으로는 데이터를 구할 수가 없다는 점입니다. 많은 분들이 질문을 하시는데 아마 온라인 블로그 등에 업데이터가 늦어 혼란이 많은 것 같습니다. 그래서 앞서 fix_yahoo_finance가 필요한 것입니다. 혹시 설치하지 않았다면 Anaconda 콘솔을 관리자 계정으로 열어 다음과 같이 입력합니다.
pip install fix_yahoo_finance
또한 구 버전의 Anaconda를 사용하고 있다면 pandas에서 에러가 발생할 수 있습니다. 그럴 때는,
conda uninstall pandas
conda install pandas
로 새로 설치해주십시오.
아래 명령어를 실행하고 나면 data.get_data_yahoo()가 정상적으로 작동합니다. 애플(AAPL)의 2011년 1월 1일부터 2012년 12월 31일까지 데이터를 구해 오겠습니다. 종가 데이터만 사용하지요.
yf.pdr_override()
price=data.get_data_yahoo('AAPL',start='2011-01-01',end='2012-12-31')['Close']
2011년 10월 3일과 2011년 3월 1일의 수익률 변화를 계산하는 방법은 다음과 같습니다.
price['2011-10-03']/price['2011-03-01']-1
그렇지만 일변 변화를 보다 더 간편하게 계산하는 pct_change()가 제공됩니다.
returns=price.pct_change()
price.head()
이제 수익지수를 구해보겠습니다. 변화율을 계속 곱하면 됩니다.
ret_index=(1+returns).cumprod()
ret_index.head()
첫 결측값을 1로 하겠습니다.
ret_index[0]=1
월 기준으로 수익지수의 변화를 보려면 resample()로 데이터를 다시 정리하면 됩니다. 인덱스를 기준으로 데이터를 축약하는 기능입니다. 자료를 참고하시기를 바랍니다.
m_returns=ret_index.resample('BM').last().pct_change() #business day, monthly
m_returns['2012']
2012년을 기준으로 월변화를 관찰했습니다.
%matplotlib inline
m_returns['2012'].plot()
댓글
댓글 쓰기