따라하면서 쉽게 배우는 판다스
Intro to Pandas¶
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
%matplotlib inline
판다스(Pandas)는 여러가지 유용한 데이터 자료구조를 제공하는 파이썬 라이브러리 입니다. 이번 콘텐츠에서는 판다스의 대표적 자료구조 형태인 Series
와 DataFrame
구조를 학습하고 실제 금융 데이터 분석에 어떻게 적용되는지 알아보도록 하겠습니다. 주피터 노트북 환경에서 작성한 문서이기 때문에 주피터 노트북을 켜고 따라서 실습해 보시면 쉽게 이해하실 수 있습니다. 주피터 노트북의 기초적인 활용법과 NumPy 모듈의 기초적인 활용법, 판다스 Series 구조를 정리한 글은 아래 콘텐츠에 링크되어 있습니다. 참고하여 진행해 주시면 되겠습니다.
판다스(Pandas)를 사용하면 손쉬운 데이터 저장, 관리, 시각화를 할 수 있습니다. 몇 줄의 코드 작성을 통해 데이터를 직관적으로 다룰 수 있습니다. 저번 NumPy 콘텐츠에서 진행했던 포트폴리오 시뮬레이션을 다음과 같이 간단하게 수행할 수 있으며 시각화도 손쉽게 가능합니다.
returns = pd.DataFrame(np.random.normal(1.0, 0.03, (100, 10)))
prices = returns.cumprod()
prices.plot(figsize=(16,9))
plt.title('Randomly-generated Prices')
plt.xlabel('Time')
plt.ylabel('Price')
plt.legend();
판다스 자료구조¶
Series
¶
판다스의 series
구조는 1차원 어레이 구조를 띄고 있으며 금융 시계열(time series)데이터를 다룰 때 매우 유용하게 사용됩니다. 시리즈는 다음과 같이 pandas.Series()
명령어를 통해 생성할수 있습니다.
s = pd.Series([1, 2, np.nan, 4, 5])
print(s)
생성된 Series
는 이름을 가지게 되며 따로 지정하지 않았다면 기본값인 None 값을 가지게 됩니다.
print(s.name)
다음과 같이 series.name
에 접근하여 이름 지정이 가능합니다.
s.name = "Practice Series"
print(s.name)
위에서 s를 출력하였을때 우리가 지정한 값들이 0,1,2,3,4 라는 숫자에 매칭되어 있는것을 확인할수 있었습니다. 이렇게 데이터 값에 매칭되어 있는 값들을 시리즈의 인덱스(index)라고 합니다. 인덱스를 따로 지정하지 않았다면 기본값인 RangeIndex가 설정됩니다. RangeIndex는 0 부터 시작하는 정수열로 리스트의 순서와 같은 개념으로 이해하시면 됩니다.
print(s.index)
날짜와 시간을 손쉽게 다룰 수 있도록 판다스는 date_range()
와 같은 날짜 인덱싱 기능을 제공합니다. 아래와 같이 날짜 인덱스를 생성 가능합니다.
# len(s) : s의 길이
new_index = pd.date_range("2016-01-01", periods=len(s), freq="D")
print(new_index)
인덱스의 길이는 해당 시리즈의 길이와 일치하여야 하기 때문에 len(s) 만큼의 기간(periods)를 할당하여 날짜 인덱스를 생성하였습니다. s의 인덱스를 새로 만든 new_index로 바꾸려면 다음과 같이 series.index
에 접근하여 바로 변경이 가능합니다.
s.index = new_index
print(s.index)
s
s의 인덱스가 날짜 형태로 바뀐것을 확인할 수 있습니다.
Series
값들에 접근하기¶
시리즈가 가지고 있는 데이터 값들에 접근하기 위해서는 iloc[]
과 loc[]
명령어에 대한 이해가 필요합니다. iloc[]
은 integer location의 약자로 "몇 번째에 있는 데이터에 접근하고 싶다!" 할때 사용합니다. loc[]
은 시리즈의 인덱스를 통해 데이터에 접근하고자 할 때 사용됩니다.
print(s.iloc[0]) # s의 0번째 값을 출력합니다.
print(s.iloc[-1]) # s의 마지막 값을 출력합니다.
iloc[]
을 사용하셨다면 이전에 배웠던 리스트 슬라이싱 기법을 적용하여 여러가지 방식으로 데이터에 접근이 가능합니다. 다음과 같이 시리즈를 손쉽게 역순으로 바꿀 수 있습니다.
# inverse the series s
s.iloc[::-1]
loc[]
을 사용한다면 인덱스의 값을 통해 해당하는 곳의 데이터에 접근이 가능합니다. 다음과 같이 2016년 1월 1일에 해당하는 값에 접근이 가능합니다.
s.loc['2016-01-01']
또는 날짜의 범위를 지정하여 해당하는 구간의 데이터에도 접근이 가능합니다.
s.loc['2016-01-02':'2016-01-04']
데이터 필터링¶
이번에는 데이터값을 필터링하여 특정한 부분에만 접근하고자 할 때 사용할 수 있는 방법들에 대해 알아보도록 하겠습니다. 위에서 생성한 s 라는 시리즈에서 데이터 값이 3보다 작은곳을 확인하고자 할때, 다음과 같이 확인이 가능합니다.
print(s<3)
인덱스와 함께 해당 조건의 진위값(True or False)가 출력됩니다. 진위값이 참(True)인 곳만 확인하고자 한다면 아래와 같이 원래 시리즈인 s에 이를 넣어주면 됩니다.
print(s.loc[s<3])
출력된 결과를 살펴보면 s<3 에서 인덱스 값이 True 인 곳만 출력된 것을 확인 가능합니다. 논리 연산자를 활용하여 복잡한 조건에 대한 필터링도 가능합니다. 아래는 1보다 크고 3보다 작은 곳을 필터링 하는 코드 입니다.
print(s.loc[(s<3) & (s>1)])
시계열 데이터 인덱싱¶
실제 주식 데이터를 읽어 시계열 데이터를 다루는 법들에 대해 정리해 봅시다. 판다스 데이터리더를 활용하여 애플 주식의 데이터를 읽어옵니다. 설치 방법과 자세한 내용은 (콘텐츠 링크 달기) 를 참고해 주세요.
import pandas_datareader as web
symbol = 'AAPL'
start = '2016-01-01'
end = '2019-03-04'
prices = web.DataReader(symbol,'iex', start, end)
prices.head()
print(type(prices))
위의 prices 는 판다스 DataFrame 타입을 가지고 있습니다. 이는 아래에서 정리하도록 하고 일단 애플의 종가데이터만 가져오도록 하겠습니다. 아래와 같이 종가(close) 데이터에 접근이 가능합니다.
close = prices['close']
print(type(close))
close의 타입이 pandas.Series 임을 확인했습니다. 아래와 같이 .head()
명령어를 사용하여 제일 위의 데이터 5개를 볼 수 있습니다.
close.head()
close 라는 시리즈의 이름을 'AAPL_close'로 설정해 줍니다.
close.name = 'AAPL_close'
close의 인덱스를 확인해 봅시다.
close.index
위의 출력 결과를 보면 dtype(데이터 타입)이 'object'라고 되어있습니다. 해당 인덱스의 첫번째 값과 그 타입을 아래와 같이 출력해 보도록 하겠습니다.
print(close.index[0])
print(type(close.index[0]))
인덱스가 문자열(str) 타입을 가지고 있습니다. 이렇게 되면 close라는 시리즈를 활용하여 시계열 데이터를 다루는데 어려움이 생기게 됩니다. 시계열 데이터를 손쉽게 다루려면 컴퓨터가 '2016-01-04' 라는 값을 2016년 1월 4일 이라고 인식해야 합니다. 하지만 위의 경우 문자 그대로 '2016-01-04' 라는 문자열 값으로 인식하게 됩니다. 따라서 아래와 같이 pd.to_datetime()
함수를 활용하여 인덱스를 날짜 형태로 바꾸어 주는 작업이 필요합니다.
pd.to_datetime(close.index)
close.index = pd.to_datetime(close.index)
type(close.index[0])
close.index의 데이터 타입이 datetime64 로 바뀐것을 확인하였습니다. 이제 파이썬은 인덱스를 날짜로 인식하게 된것입니다.
판다스를 활용한 시계열 분석¶
위의 close 시리즈를 활용하여 간단한 분석을 진행해 보도록 하겠습니다. 먼저 그래프를 그려 간단하게 시각화가 가능합니다.
close.plot(figsize=(16,9)); # 그래프의 사이즈를 정해 줍니다.
plt.title(symbol + 'Close Price') # 제목을 설정합니다.
plt.ylabel('Close') # y축의 라벨을 설정합니다.
plt.xlabel('Date'); # x축의 라벨을 설정합니다.
pandas.Series.describe()
메서드를 활용해 간단한 통계적 정보를 확인 가능합니다.
print('Summary Statistics')
print(close.describe())
시리즈에 숫자(스칼라)를 곱하거나(나누거나) 더해서(빼서) 다음과 같이 쉽게 변형이 가능합니다.
edited_close = close * 10 - 10
edited_close.head()
시리즈 끼리의 기본적인 연산도 가능합니다. 시리즈 끼리 연산을 하면 같은 인덱스에 해당 하는 값들 끼리 연산을 한 뒤 결과를 출력합니다. 다음과 같이 시리즈를 더해보도록 하겠습니다.
a = pd.Series([1,2,3])
b = pd.Series([1,2])
a + b
같은 인덱스에 해당하는 값끼리 더하기 때문에 인덱스 0과 1번에 해당하는 값들은 더해져서 2와 4가 출력되었고 2번 인덱스의 경우 b라는 시리즈에 해당하는 인덱스의 값이 없기 때문에 더하기 연산을 수행할 수 없게되고 NaN(Not a Number) 값이 출력됩니다. 이렇게 NaN값이 출력되는 것을 방지하기 위해 아래와 같이 add()
연산과 fill_value
를 0으로 설정하면 비어있는 값에 대해서는 0이 더해져 아래와 같이 출력됩니다.
a.add(b, fill_value=0)
곱하기의 경우도 같은 방식으로 계산이 가능합니다. 덧셈과 마찬가지로 특정 인덱스에 해당하는 값이 없어서 연산이 불가능하면 NaN이 출력됩니다.
a * b
곱하기 기호대신 multiply()
연산과 fill_value
값을 1로 설정하면 다음과 같은 결과를 얻을 수 있습니다.
a.multiply(b, fill_value=1)
아래와 같이 noise 텀을 만들어서 노이즈가 낀 가격 데이터를 만들 수 있습니다.
noise = pd.Series(np.random.normal(0,5,len(close)), index=close.index) + 20
noise.head()
noisy_price = close + noise
noisy_price.head()
시계열 데이터 분석에서 많이 사용되는 차분(difference)과 퍼센트 수익률(percent return)을 내장된 함수를 통해 손쉽게 계산이 가능합니다.
diff()
메서드를 사용해 차분(difference)을 쉽게 계산 가능합니다.
pct_change()
메서드를 사용해 퍼센트 수익률(percent return)을 쉽계 계산 가능합니다.
add_returns = close.diff()[1:]
percent_returns = close.pct_change()[1:]
plt.title("Percent returns of " + symbol)
plt.xlabel("Date")
plt.ylabel("Percent Returns")
percent_returns.plot(figsize=(16,9));
시계열 데이터를 분석할 때 특정기간(window)를 rolling 하면서 값들을 계산해야 할 상황이 많이 있습니다. 대표적으로 주식 차트 분석에서 널리 사용되는 이동평균선이 있습니다. 시리즈에 내장된 rolling
기능을 활용해 이런 값들을 손쉽게 계산할 수 있습니다.
# 20일간의 기간(window)를 설정하여 rolling mean을 계산합니다.
moving_average = close.rolling(window=20).mean()
moving_average.name = '20-day moving average'
close.plot(figsize=(16,9))
moving_average.plot();
plt.title(symbol + "Price")
plt.xlabel("Date")
plt.ylabel("Price")
plt.legend();
이동평균 뿐만 아니라 표준편차도 같은 방식으로 rolling 하면서 계산이 가능합니다.
moving_std = close.rolling(window=20).std()
moving_std.name = '20-day moving volatillity'
moving_std.plot(figsize=(16,9));
plt.title(moving_std.name);
plt.xlabel('Date')
plt.ylabel('Standard Deviation');
넘파이의 많은 계산 함수들이 시리즈에 내장되어 있어 손쉽게 사용가능합니다. 중간값인 median을 다음과 같이 2가지 방법으로 계산할 수 있습니다.
print(np.median(mult_returns))
print(mult_returns.median())
Intro to Pandas DataFrame¶
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
%matplotlib inline
from jupyterthemes import jtplot
jtplot.style('grade3')
pandas.DataFrame¶
저번 콘텐츠에서 배운 pandas.Series의 개념들은 판다스의 또다른 대표적 자료구조인 pandas.DataFrame에서도 그대로 적용이 가능합니다. 데이터 프레임은 특정 인덱스를 갖는 2차원 테이블 이라고 생각하시면 쉽게 이해할 수 있습니다. 인덱스인 날짜와 해당 날짜의 시가(open), 고가(high), 저가(low), 종가(close), 거래량(volume)의 정보를 가지고 있는 일반적인 주가데이터나 엑셀의 스프레드시트를 떠올리시면 됩니다. 저번 콘텐츠에서 아래와 같이 pandas_datareader모듈을 사용하여 가격정보를 불러왔었습니다. prices라는 변수에 저장된 가격정보는 데이터프레임 타입을 가지고 있습니다.
import pandas_datareader as web
symbol = 'AAPL'
start = '2016-01-01'
end = '2019-03-04'
prices = web.DataReader(symbol,'iex', start, end)
prices.head()
print(type(prices))
DataFrmae은 pandas.DataFrame() 함수를 사용해 생성이 가능하며 함수안에 dictionary 또는 넘파이 ndarray를 입력하면 해당 객체가 dataFrame으로 변경됩니다. 또한 여러개의 Series를 pandas.concat() 메서드를 활용하여 dataFrame으로 합성이 가능합니다. 이 외에 다른 기능들은 판다스 데이터프레임 공식문서를 참고하시면 됩니다. 여기서는 dictionary를 데이터 프레임으로 변환해 보겠습니다.
dict_data = {
'a' : [1, 2, 3, 4, 5],
'b' : ['L', 'K', 'J', 'M', 'Z'],
'c' : np.random.normal(0, 1, 5)
}
print(dict_data)
Series를 생성할 때와 같이 손쉽게 날짜 인덱싱이 가능합니다.
frame_data = pd.DataFrame(dict_data, index=pd.date_range('2016-01-01', periods=5))
frame_data
위에서 언급했던 여러개의 Series 구조를 하나의 DataFrame으로 합칠수 있습니다. pandas.concat() 메서드를 활용할 경우 axis라는 키워드를 통해 합칠 방향(0:세로방향, 1:가로방향)을 정할 수 있으며, 자동으로 같은 인덱스끼리 데이터가 정렬되어 하나의 데이터프레임으로 합쳐지게 됩니다. 아래 예제의 경우 두 시리즈 모두 같은 정수형 인덱스를 가지기 때문에 다음과 같이 합쳐지게 됩니다.
s_1 = pd.Series([2, 4, 6, 8, 10], name='Evens')
s_2 = pd.Series([1, 3, 5, 7, 9], name="Odds")
numbers = pd.concat([s_1, s_2], axis=1)
numbers
위에서 불러온 prices 데이터 프레임을 바탕으로 몇가지 명령어들을 살펴보도록 하겠습니다. DataFrame.head() 명령어를 통해 상위 5개의 데이터를 살펴볼 수 있습니다. 괄호안에 숫자를 입력하면 해당 개수만큼 데이터를 가져옵니다.
prices.head()
DataFrame.columns 명령어를 사용해 해당 데이터프레임의 열(column) 목록을 확인 가능하며 다른 리스트 값을 집어넣어 변경또한 가능합니다.
prices.columns
시리즈와 같이 인덱스(index)에 접근이 가능하며 저번 콘텐츠에서 처럼 날짜형식으로 인덱스를 바꾸어 주도록 하겠습니다.
prices.index = pd.to_datetime(prices.index)
prices.index
DataFrame.values 명령어를 통해 인덱스와 columns를 제외한 내용물값 데이터만을 받아올 수 있습니다.
prices.values
DataFrame.values 를 통해 불러온 값은 넘파이 어레이(ndarray) 타입을 가집니다.
type(prices.values)
DataFrame 값들에 접근하기¶
DataFrame은 2차원 테이블 형태입니다. DataFrame의 특정 열이나 행에 접근할 수 있는 방법들에 대해 알아보도록 하겠습니다. 먼저 특정 열(column)에 접근하고자 할 경우 다음과 같이 DataFrame.열이름 과 같이 해당 열에 접근이 가능합니다. 위에서 불러온 테이블에서 종가(close)가 담겨있는 열에 접근해 보도록 하겠습니다.
prices.close.head()
또다른 방법으로는 DataFrame.[열이름] 과 같은 방식으로도 접근이 가능합니다.
prices['close'].head()
마지막 방법으로 아래와 같이 loc[] 명령어를 사용하여 접근이 가능합니다. 이 방법이 판다스에서 가장 권장하는 방법입니다.
prices.loc[:,'close'].head()
DataFrame에서 특정 열에 접근했다면 그 결과는 무조건 Series 타입을 가지게 됩니다.
print(type(prices.close))
print(type(prices['close']))
Series에서와 달리 DataFrame은 2차원 구조를 가지기 때문에 loc[] 메서드에 들어가는 입력값이 2개 입니다. 아래와 같이 열이름으로 구성된 리스트를 입력하여 여러 열을 한번에 가져올 수 있습니다.
prices.loc[:,['close','volume']].head()
Series에서 처럼 loc[] 명령어에 인덱스 범위를 입력하여 해당되는 값들에 접근이 가능합니다.
prices.loc['2016-01-01':'2016-01-10']
위의 두 예제를 조합하면 다음과같이 원하는 인덱스와 원하는 열의 데이터에 접근이 가능합니다.
prices.loc['2016-01-01':'2016-01-10', ['close', 'volume']]
다음과 같이 범위를 지정하면 2016년 1월 한달의 애플 주가데이터에 접근이 가능합니다.
prices.loc['2016-01':'2016-01']
iloc[] 또한 Series에서처럼 동일하게 사용이 가능합니다.
prices.iloc[0:10,1]
다음과 같이 리스트 슬라이싱 기법을 활용하여 홀수번 행(row)에 접근이 가능합니다. iloc[]은 0번 부터 시작하기 때문에 아래와 같이 접근할 경우 홀수번째 행에 접근함을 의미합니다.
prices.iloc[::2].head()
데이터 필터링¶
Series에서 처럼 DataFrame도 데이터를 필터링 할 수 있는 기능을 제공합니다. prices 데이터로 캔들차트를 그렸을 때 양봉이 되는 날을 필터링 해보도록 하겠습니다. 캔들차트에 대한 설명은 주식 왕초보자들을 위한 용어 설명 2 - 시고저종, 거래량, 그리고 거래대금 콘텐츠를 참고해 주세요!
파이썬으로 캔들차트 그리는 방법은 [누구나 따라 하는 금융데이터 분석] - 파이썬에서 캔들차트 그리기 게시물을 참고해 주세요!
특정한 날의 캔들차트가 양봉이라는 것은 해당일의 종가(close)가 시가(open)보다 높게 장이 마감했다는것 입니다. 이를 아래와 같이 직관적인 조건식으로 필터링이 가능합니다.
prices.loc[prices.close > prices.open].head()
조건식에 논리연산자를 추가하여 더욱 복잡한 필터링이 가능합니다. 종가가 시가대비 3% 이상 상승한 양봉을 찾아보도록 하겠습니다. 위의 양봉 조건에 시가대비 종가의 상승률이 0.03 보다 크다는 조건을 추가하여 필터링이 가능합니다.
prices.loc[(prices.close > prices.open) &
((prices.close - prices.open)/prices.open > 0.03)].head()
데이터 프레임 조작하기¶
기존의 데이터 프레임에 다른 데이터를 추가하거나 특정한 곳을 제거하려면 어떻게 해야 할까요? 그 방법들을 알아보도록 하겠습니다. 먼저 prices DataFrame에서 거래량 정보를 volume이라는 변수에 따로 저장해 둡니다.
volume = prices.loc[:,'volume']
type(volume)
특정 열(column)을 제거하려면 DataFrame.drop('열 이름', axis=1)이라고 입력한 뒤 실행하시면 됩니다. 아래와 같이 prices 에서 거래량 정보를 제거하겠습니다. 출력결과 거래량 정보가 삭제되었음을 확인가능합니다.
prices = prices.drop('volume', axis=1)
prices.head()
DataFrame에 새로운 열을 추가하고자 할 때에는 단순히 DataFrame.loc[:, '추가할 열 이름']
에 추가할 데이터를 할당해 주면 됩니다. 제거했던 거래량 정보(volume : Series)를 다시 prices DataFrame에 추가해 보도록 하겠습니다. 출력결과 거래량(volume) 열이 추가된것을 확인가능합니다.
prices.loc[:,'volume'] = volume
prices.head()
여러 DataFrame을 합치고자 할 경우 pandas.concat() 메서드를 활용하여 병합이 가능합니다. 아래와 같이 prices 데이터에서 두 개의 DataFrame을 분리해 봅시다.
open_and_high = prices.loc[:, ['open', 'high']] # 시가와 고가를 담은 데이터프레임
low_and_close = prices.loc[:, ['low', 'close']] # 저가와 종가를 담은 데이터프레임
위의 두 DataFrame을 pd.concat() 메서드를 활용하여 아래와 같이 합칠수 있습니다.
ohlc = pd.concat([open_and_high, low_and_close], axis=1)
ohlc.head()
데이터프레임을 활용한 간단한 시계열 분석¶
Series와 같이 DataFrame에도 시계열 데이터 분석을 편리하게 해줄 내장함수들이 많이 있습니다. 이를 활용하면 데이터프레임에 들어있는 여러 시계열 데이터(time series data)에 동시에 연산들을 적용할 수 있습니다. 위의 판다스 시리즈 분석에 쓰인 방법들과 거의 비슷하니 천천히 따라오시면 이해하시기 쉬울것 입니다.
DataFrame.plot() 메서드를 활용하여 여러가지 데이터를 한번에 차팅이 가능합니다. 열(column)이름이 자동으로 범례(legend)로 지정되어 있음을 확인가능합니다.
# 캔들차트 그리기는 링크 걸기
ohlc.plot(figsize=(16,9))
plt.title(symbol + ' OHLC')
plt.ylabel('Price')
plt.xlabel('Date');
Series에서 사용하였던 기본적인 통계량 계산 함수들도 그래도 사용가능합니다. 여기서 Series와 다른점은 괄호안에 axis라는 파라미터가 들어간다는것 입니다. 이는 해당 함수를 계산하는 방향을 나타내며 행(row)을 따라가며 계산을 할 경우 axis=0
, 열(column)을 따라가며 계산할 경우 axis=1
을 입력해 주면 됩니다. 아래 예제를 보면 쉽게 이해가 가능합니다.
prices.mean(axis=0)
prices.std(axis=0)
Series와 마찬가지로 describe() 메서드를 활용하여 요약된 통계량 정보를 한눈에 확인 가능합니다.
prices.describe()
스칼라 계산도 Series와 마찬가지로 각각 데이터에 적용됩니다.
(100 * prices - 100).head()
게시글의 첨부파일을 보시면 close_data.csv 라는 파일이 있습니다. 해당 엑셀파일은 코스피, 삼성전자 그리고 SK하이닉스의 2018년 동안의 수정종가를 담고있는 파일입니다.
pandas는 엑셀 csv 파일을 DataFrame으로 읽어올 수 있는 기능을 제공합니다. 첨부파일에 있는 csv파일을 현재 실행중인 주피터노트북이 저장된 폴더에 저장해 주시고 다음과 같이 pd.read_csv함수를 활용해 csv파일의 데이터를 읽어 옵니다.
# dt열을 인덱스 열로 지정하여 데이터를 읽어옵니다.
close_prices = pd.read_csv('close_data.csv', index_col='dt')
close_prices.head()
close_prices.tail() # 마지막 5개의 데이터를 확인합니다.
csv 파일을 데이터가 정상적으로 읽어졌음을 확인하였습니다. 인덱스의 데이터 타입을 체크해 보도록 하겠습니다.
type(close_prices.index[0])
저번처럼 문자열 타입이기 때문에 파이썬이 날짜로 인식하도록 아래와 같이 인덱스를 datatime형식으로 변경해 줍니다.
close_prices.index = pd.to_datetime(close_prices.index)
각 종목별 퍼센트 수익률을 시리즈에서 처럼 pct_change() 메서드를 활용해 손쉽게 계산 가능합니다.
mult_returns = close_prices.pct_change()[1:]
mult_returns.columns = ['KOSPI_return','SAMSUNG_return','SK_Hynix_return']
mult_returns.head()
종목간의 직관적 가격 움직임의 비교를 위해 같은 스케일에서 움직이도록 정규화를 진행합니다. norm_returns 라는 새로운 DataFrame에 종목별로 정규화 시킨 값들을 저장하여 그래프를 출력합니다.
norm_returns = (mult_returns - mult_returns.mean(axis=0))/mult_returns.std(axis=0)
norm_returns.plot(figsize=(16,9));
각 종목의 20일 이동평균선을 구해보도록 하겠습니다. 시리즈에서 처럼 rolling(window=20)과 같은 메서드를 활용하여 손쉽게 계산이 가능합니다.
moving_average = close_prices.rolling(window=20).mean()
moving_average.columns = ['KOSPI-MA20','SAMSUNG-MA20','SK_Hynix-MA20']
moving_average.plot(figsize=(16,9))
plt.title("20 Days Moving Average of Close Prices")
plt.xlabel("Date")
plt.ylabel("Price")
plt.legend();
</html>