pandas와 plotly를 이용하여 신라젠이라는 기업의 주식 종가를 시계열로 만들었다.
자료의 소스는 아래 참조의 EXCELSIOR 블로그의 Excelsior-JH님의 코드에 주석을 더 달아놓은 것이다.
========================== Python ==========================
# 한국 거래소 데이터 => 종목코드
# 네이버 금융에 특정 기업을 분석한다. 분석 대상은 신라젠이라는 기업.
# jupyter notebook은 반드시 크롬에서 실행한다.
import pandas as pd
# html에 있는 정보를 읽어온다.
# header = 0 으로 맨 윗줄의 데이터를 헤더로 사용하고 얻은 자료를 리스트 형태로 이용하기 위해 뒤에 [0] 을 붙여준다.
code_df = pd.read_html('http://kind.krx.co.kr/corpgeneral/corpList.do?method=download&searchType=13', header=0)[0]
# 타입을 확인
print(type(code_df)) # <class 'pandas.core.frame.DataFrame'>
print(code_df.head()) # 데이터를 확인
# code_df에 있는 '종목코드' 컬럼을 0을 채운 6자리 포멧으로 맞춰준다.
code_df.종목코드 = code_df.종목코드.map('{:06d}'.format)
# code_df를 회사명과 종목코드 컬럼만 뽑아낸다.
# ***참고*** pandas에서 컬럼을 선택 할 때
# 단일개 선택: df['컬럼명'] or df.컬럼명
# 여러개 선택: df[['컬럼명', ... ,'컬럼명']]
code_df = code_df[['회사명', '종목코드']]
print(code_df) # 데이터를 확인
# 한글로된 컬럼명을 영어로 바꿔준다.
code_df = code_df.rename(columns={'회사명': 'name', '종목코드': 'code'})
# 신라젠 네이버 금융 주소. http://finance.naver.com/item/main.nhn?code=215600
# 함수 생성 => 특정한 업체만 코드를 가져오기 위해서
def get_url(item_name, code_df):
# 코드를 가져오기 위한 처리.
# 먼저 .query("name=='{}'".format(item_name))['code']는 name 컬럼에 item_name과 동일한 값의 code값을 반환한다는 뜻.
# 즉, .query("쿼리".format(쿼리에 넣을 데이터))[얻을 자료]
# .to_string(index = False)로 위에서 얻어진 값에 index를 빼고 string타입으로 바꿔준다.
code = code_df.query("name=='{}'".format(item_name))['code'].to_string(index = False)
# url은 일일 종가 시가 고가 저가 거래량을 보여주는 표이다.
url = 'http://finance.naver.com/item/sise_day.nhn?code={code}'.format(code = code)
print("요청 URL = {}".format(url))
return url
# 신라젠 정보 가져오기
item_name = '신라젠'
url = get_url(item_name, code_df)
df = pd.DataFrame()
# 크롤링. 페이지 20까지 크롤링을 한다.
for page in range(1, 21):
# 위에서 얻은 url에 page를 붙여줘서 url 포멧을 만들어준다.
pg_url = '{url}&page={page}'.format(url = url, page = page)
# pandas의 df에 위에서 얻은 url을 넣어줘서 우리가 구하고자 하는 데이터프레임을 만든다.
# 데이터프레임을 만들 때 리스트에 [0]을 붙여줘서 만들 수 있음을 다시 확인.
df = df.append(pd.read_html(pg_url, header = 0)[0], ignore_index= True)
# df.dropna()를 이용해 결측값(NaN) 있는 행을 제거한다.
df = df.dropna()
# 상위 5개 데이터 확인하기
print(df.head())
# 한글로 된 컬럼명을 영어로 바꿔준다.
df = df.rename(columns= {'날짜': 'date', '종가': 'close', '전일비': 'diff',
'시가': 'open', '고가': 'high', '저가': 'low', '거래량': 'volume'})
# 데이터의 타입을 int형으로 바꿔줌. \(역슬래쉬)는 뒤에 데이터가 이어진다는 의미이다. 한줄로 쓰면 \ 필요없음.
df[['close', 'diff', 'open', 'high', 'low', 'volume']]\
= df[['close', 'diff', 'open', 'high', 'low', 'volume']].astype(int)
# 컬럼명 'date'의 타입을 date로 바꿔줌
df['date'] = pd.to_datetime(df['date'])
# 일자(date)를 기준으로 오름차순 정렬
df = df.sort_values(by=['date'], ascending=True)
# 상위 5개 데이터 확인
print(df.head())
# 시각화 파트
# jupyter notebook 에서 출력. 꼭 jupyter notebook에서 해야한다.
# 만약 jupyter notebook에서 출력하기 싫다면 아래에 적어놓는 방법을 이용하자.
import plotly.offline as offline
import plotly.graph_objs as go
# plotly 접속
offline.init_notebook_mode(connected=True)
# 그래프를 생성. x축에는 날짜, y축에는 종가, 그래프 이름은 item_name에서 가져온다.
trace = go.Scatter(x=df.date, y=df.close, name=item_name)
# 위에 데이터 정보를 data라는 객체의 리스트로 담아준다.
data = [trace]
# 레이아웃 잡기
layout = dict(title='{}의 종가(close) Time Series'.format(item_name), # 타이틀 생성.
xaxis=dict(
rangeselector=dict(
buttons=list([ # 한 달, 세 달, 6달, 전체 종가를 보여주는 버튼을 만든다.
dict(
count=1, # 1개씩 센다. 여기서는 step='month'이기 때문에 1달이 된다.
label='1m', # 라벨 이름. 그래프에 1m이라는 버튼을 만든다.
step='month', # 한 달을 기준으로 잡아서 count를 센다.
stepmode='backward'), # 가장 최근 데이터부터 센다. forward는 가장 오래된 데이터부터 센다.
dict(
count=3,
label='3m',
step='month',
stepmode='backward'),
dict(
count=6,
label='6m',
step='month',
stepmode='backward'),
dict(
step='all') ]) ), # 전체 데이터를 출력한다. step='all'은 label을 설정할 수 없다.
rangeslider=dict(),
type='date'
)
)
# graph object에 data, layout을 저장한다.
fig = go.Figure(data=data, layout=layout)
# 플롯을 출력한다.
offline.iplot(fig)
# jupyter notebook 에서 출력하기 싫을 때 사용하는 방법.
# html로 만든다.
import plotly.offline as offline
import plotly.graph_objs as go
# # plotly 접속
# offline.init_notebook_mode(connected=True)
# 그래프를 생성. x축에는 날짜, y축에는 종가, 그래프 이름은 item_name에서 가져온다.
trace = go.Scatter(x=df.date, y=df.close, name=item_name)
# 위에 데이터 정보를 data라는 객체의 리스트로 담아준다.
data = [trace]
# 레이아웃 잡기
layout = dict(title='{}의 종가(close) Time Series'.format(item_name), # 타이틀 생성.
xaxis=dict(
rangeselector=dict(
buttons=list([ # 한 달, 세 달, 6달, 전체 종가를 보여주는 버튼을 만든다.
dict(
count=1, # 1개씩 센다. 여기서는 step='month'이기 때문에 1달이 된다.
label='1m', # 라벨 이름. 그래프에 1m이라는 버튼을 만든다.
step='month', # 한 달을 기준으로 잡아서 count를 센다.
stepmode='backward'), # 가장 최근 데이터부터 센다. forward는 가장 오래된 데이터부터 센다.
dict(
count=3,
label='3m',
step='month',
stepmode='backward'),
dict(
count=6,
label='6m',
step='month',
stepmode='backward'),
dict(
step='all') ]) ), # 전체 데이터를 출력한다. step='all'은 label을 설정할 수 없다.
rangeslider=dict(),
type='date'
)
)
# graph object에 data, layout을 저장한다.
fig = go.Figure(data=data, layout=layout)
# 플롯을 출력한다.
offline.iplot(fig)
# 여기까지 끝나면 temp-plot.html이 생성되는데 이걸 출력하면 jupyter에서 출력되는 것과 동일한 그래프가 나온다.
# 경로와 이름을 지정하고 싶으면 offline.plot(fig, filename = '원하는 경로/원하는 이름.html')을 하면 된다.
========================== Python ==========================
ref.
EXCELSIOR
http://excelsior-cjh.tistory.com/109
'데이터 분석 > 데이터 분석 프로젝트' 카테고리의 다른 글
[설문조사 분석] Python으로 분석한 Kaggle 2017 Survey -2 (0) | 2018.06.22 |
---|---|
[설문조사 분석] Python으로 분석한 Kaggle 2017 Survey -1 (0) | 2018.06.21 |
[시계열, 트렌드 분석] 단역배우 자매 사망 사건의 시계열 및 트렌드 분석 -2(개요, 관심도 변화) (0) | 2018.06.14 |
[시계열 분석] 단역배우 자매 사망 사건의 시계열 및 트렌드 분석 -1(준비 단계) (0) | 2018.06.07 |
[R] mpg 데이터를 이용한 자동 회귀분석 모델 이용 -2 (0) | 2018.05.30 |