[python 데이터분석]파이썬으로 로또 당첨번호 및 당첨금 데이터 분석 하기 feat.pandas, pyplot
[python 데이터분석]파이썬으로 로또 당첨번호 및 당첨금 데이터 분석 하기 feat.pandas, pyplot
안녕하세요.
파이썬 데이터 분석 해보겠습니다.
이번 데이터 분석은 첨으로 온전한 저 스스로 하는 데이터 분석 입니다.
그래서 조금 허접 할 수 있다는 점! 미리 알려드립니다..ㅎㅎ
이번 시간에 하는 분석은 로또 1등 당첨번호중 그 빈도를 추출 하는 것과 당첨금 데이터 추이를 확인 해 보겠습니다.
로또 1등 당첨번호 및 당첨금에 대한 데이터는 이전에 포스팅했던 로또 당첨번호 및 당첨금 데이터 크롤링 한걸 엑셀 파일로 저장 하는 포스팅을 했었는데 거기서 저장 한 데이터를 이용 했습니다.
2020/01/16 - [DB엔지니어가 공부하는 python] - [python] 파이썬으로 역대 로또 당첨번호, 1등 당첨금 수집 후 엑셀,텍스트 파일에 저장 feat.미완성
위 포스팅을 참고 하시면 됩니다.
바로 시작 하겠습니다.
우선 위에서 크롤링한 데이터를 저장 한 엑셀 파일을 불러 옵니다.
import pandas as pd
import matplotlib as mpl
import matplotlib.pyplot as plt
라이브러리 선언 부터 하구요, pandas와 matplotlib, pyplot 을 선언해 줍니다.
엑셀 파일도 불러오구요~!
df=pd.read_csv("./lotto_number_history.csv")
df.head(50)
이렇게 데이터가 잘 불러져 온것을 확인 할 수 있습니다.
컬럼명에 대해서 설명 드리고 가겠습니다.
seq - 회차
date - 추첨일
sell_amount - 총판매금액
total_reward - 1등당첨금총액
winner_cnt - 1등당첨자수
winner_reward - 1인당1등당첨금액
no1 - 첫번째 번호
no2 - 두번째 번호
no3 - 세번째 번호
no4 - 네번째 번호
no5 - 다섯번째 번호
no6 - 여섯번째 번호
bn - 보너스 번호
이렇게 데이터가 구성 되어 있습니다.
그럼 이젠 총 데이터 요약을 확인 해 보겠습니다.
요약정보로만으로도 많은 정보를 확인 할 수 있습니다.
df.describe()
이렇게 보니, 숫자에 'e+...' 어쩌구 이렇게 나오네요.
데이터가 저렇게 나오면 곤란하니, 아래 명령어로 실수를 다 표시 하도록 변경 합니다.
pd.options.display.float_format = '{:.2f}'.format
짜잔! 이렇게 숫자가 잘 나오고 있습니다.
하지만 천자리마다 찍히는 , 콤마가 없으니 얼마인지 눈에 한번에 들어오지 않습니다.
해결해 볼께요!
pd.options.display.float_format = '{:,.2f}'.format
이렇게 포멧을 변경해줍니다. 이러면,
이렇게 보기 좋은 그림으로 숫자들이 표시되고 있는것을 확인 할 수있습니다.
여기서 확인 할 수있는건 평균적인 1인당 1등 당첨금액이 약 27억원 정도 된다는것을 알 수 있습니다.
또한 한 회당 평균 약 7명(6.88명)이 1등에 당첨되고 있다는 사실도 알 수 있으며,
1인당 최고 1등 당첨금은 약 407억원임을 알 수 있습니다.
또한 총 판매금액이 가장 많은건 2,608억원이 였습니다.
왜 이렇게 이 회차에는 판매금이 큰걸까요?
2,608억원의 판매금이 나온 회차는 10회차 였는데요, 7,8,9회차에서 1등이 나오지 않으면서 이월되었던것을 확인 할 수 있습니다. 이월 되면서 사람들의 1등 당첨에 대한 기대감이 커졌던것으로 추측 할 수 있습니다.
총판매금액 추이에 대한 그래프를 한번 그려 보겠습니다.
df['sell_amount'].plot(figsize=(20,6))
plt.legend()
plt.show()
총 판매금액은 전반적으로 초반에 높았다가 시간이 갈수록 약간씩 올라가는 모습을 볼 수 있습니다.
다만 2002년 판매개시때 바짝 올라 갔으나, 2008년까진 약간 하락세를 보이는 것도 볼 수 있습니다.
1등당첨금총액에 대한 그래프도 그려 볼까요? 이번엔 빨간색으로..
df['total_reward'].plot(figsize=(20,6),color = 'red')
plt.legend()
plt.show()
위에서 확인한 총판매금액 의 추이와 비슷하다는 걸 알 수 있습니다.
아마 로또 당첨 확률은 항상 일정하다는걸 확인 할 수 있는 그래프라 생각 되어 집니다.
자, 다음은 로또 1등당첨번호별 빈도를 살펴 보겠습니다.
당첨번호는 no1,no2...no6에 저장 되어 있습니다.
우선, 이 번호들을 각각의 데이터 셋으로 저장해 보겠습니다.
df1=df[['no1']]
df2=df[['no2']]
df3=df[['no3']]
df4=df[['no4']]
df5=df[['no5']]
df6=df[['no6']]
이런식으로 데이터가 저장 됩니다.
그럼 이걸 가지고 각각 데이터셋에 어떤번호가 몇번 나왔는지 group by count를 해줍니다.
df1_cnt=df1['no1'].value_counts()
df2_cnt=df2['no2'].value_counts()
df3_cnt=df3['no3'].value_counts()
df4_cnt=df4['no4'].value_counts()
df5_cnt=df5['no5'].value_counts()
df6_cnt=df6['no6'].value_counts()
이렇게 df1을 가지고 df1_cnt를 만들어줍니다. 그렇게 6개의 데이터셋을 모두 처리 해줍니다.
이렇게 몇번 번호가 몇번 나왔는지 각 데이터 셋마다 저장이 되어 집니다.
이런 데이터셋이 6개 있겠죠? 그것들은 join해서 6개 데이터셋 모두를 합쳐 줍니다.
df1_cnt 와 df2_cnt를 join 해주고, 그 결과를 df3_cnt와 조인하면서 그렇게 6개를 다 join 해줍니다.
df_join2=pd.merge(df1_cnt_df,df2_cnt_df,left_index=True,right_index=True,how='outer')
df_join3=pd.merge(df_join2,df3_cnt_df,left_index=True,right_index=True,how='outer')
df_join4=pd.merge(df_join3,df4_cnt_df,left_index=True,right_index=True,how='outer')
df_join5=pd.merge(df_join4,df5_cnt_df,left_index=True,right_index=True,how='outer')
df_join6=pd.merge(df_join5,df6_cnt_df,left_index=True,right_index=True,how='outer')
이렇게 DataFrame을 통해서 데이터 셋의 조인 하는 방법은 아래 블로그에 잘 나와 있으니 참고 하시기 바랍니다.
https://rfriend.tistory.com/259
이렇게 데이터셋의 join이 끝나게 되면 아래와 같은 모습을 가진 데이터가 됩니다.
원래 join을 하게 되면 12.00 이런식으로 소숫점 뒤 두자리가 보이는데, 이걸 정수로만 표현하려면 아래 기능을 사용 하시면 됩니다.
pd.options.display.float_format = '{:,.0f}'.format
그리고나서 값을 확인 해 보겠습니다.
이젠 여기에다가 cnt_sum 이라는 컬럼을 만들어서 각 숫자별 cnt를 합쳐주겠습니다.
우선 cnt_sum 이라는 함수를 하나 선언해 줍니다.
def cnt_sum(dt):
return (dt['no1']+dt['no2']+dt['no3']+dt['no4']+dt['no5']+dt['no6'])
그리고 이 함수를 이용해서 cnt_sum에 값을 넣어 보겠습니다.
df_join6['cnt_sum'] = df_join6.fillna(0).apply(cnt_sum, axis=1)
여기에서 fillna(0)을 호출한 이유는 위 데이터를 보시면 알겠지만 nan으로 된 빈값들이 있어서 해당 값을 0으로 치환 하겠다는 의미로 쓰입니다. 그래야 더해질수 있을테닌깐요.
그렇게 더해진 값이 cnt_sum에 update가 되었으니 확인 해 보겠습니다.
오우! 잘 저장된 것을 확인 할 수 있습니다.
그럼 이젠 각 로또 번호별 1등번호로 기출된 횟수를 찾았습니다.
기출 횟수로 정렬을 해서 보겠습니다.
df_join6.sort_values(by = 'cnt_sum', ascending = False)
ascending을 False로 하여 desc 정렬이 되도록 합니다.
이렇게 보닌깐 34, 43, 27, 17, 40 번의 순으로 많이 나오고 있음을 알 수 있습니다.
그럼 1회당 어떤 번호가 당첨번호로 나올 확률도 구해 볼까요? rate라는 컬럼을 하나 더 만들어서 확률을 구해 넣어 보겠습니다.
def rate(dt):
return (dt['no1']+dt['no2']+dt['no3']+dt['no4']+dt['no5']+dt['no6'])/897*100
# rate 라는 함수를 만들고, 총 회차인 897로 나누고 100을 곱하여 줍니다.
df_join6['rate'] = df_join6.fillna(0).apply(rate, axis=1)
# rate라는 컬럼을 만들어 rate 함수의 결과를 update 합니다.
pd.options.display.float_format = '{:.2f}'.format
# 그리고 소숫점 두자리까지 볼 수 있도록 변경 합니다.
df_join6
# 데이터를 확인 합니다.
이 확률 데이터를 이요하여 그래프를 한번 그려볼께요.
df_join6['rate'].plot(figsize=(20,6),color = 'yellow')
plt.legend()
plt.show()
자, 이것으로... 이번 데이터 분석은 마쳐보겠습니다.
사실 이 방법 보다 더 간단한 방법이 있을꺼라고 전 확신 합니다만..
전, 아직 파린이닌깐요.... 여러 단계를 거치면서 데이터를 핸들링 하는 방법을 익혀본다고.. 스스로 위안을 삼아 봅니다.
많이 부족한 글 읽어 주셔서 감사드립니다.
혹시라도 좋은 방법이나 이 데이터로 할 수있는 다른 분석에 대한 아이디어가 있으시면 댓글로 공유 부탁드립니다!
오늘도 좋은 하루 되시길 바랍니다.
감사합니다.
by.sTricky