반응형
In [268]:
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib
import os
from IPython.display import HTML
import seaborn as sns
from IPython.display import display
pd.options.display.max_columns = None
%matplotlib inline
# 한글 폰트
plt.rcParams['font.family'] = 'NanumGothicCoding'
# 마이너스 깨짐 방지
matplotlib.rcParams['axes.unicode_minus'] = False
In [269]:
os.listdir('./datas')
Out[269]:
['Regular_Season_Batter_Day_by_Day_b4.csv', 'Regular_Season_Batter.csv', 'submission.csv', 'Pre_Season_Batter.csv']
데이터 살펴보기¶
In [270]:
# HTML 파일 내용 읽어오기
with open('./data_table_description.html', 'r') as f:
html_content = f.read()
# HTML 내용 출력
print('데이터 도메인')
HTML(html_content)
데이터 도메인
Out[270]:
Column Name | Pre/Regular_Season_Batter | Regular_Season_Batter_Day_by_Day | Submission |
---|---|---|---|
batter_id | 타자 고유 ID | 타자 ID | 선수 고유 ID |
batter_name | 타자 이름 | 타자 이름 | 선수 이름 |
year | 년도 | 년도 | |
team | 소속 팀 | ||
avg | 타율 | ||
avg1 | 해당 경기 타율 | ||
avg2 | 시즌 누적 타율 | ||
G | 경기 | ||
AB | 타수 | 타수 | |
R | 득점 | 득점 | |
H | 안타 | 안타 | |
2B | 2루타 | 2루타 | |
3B | 3루타 | 3루타 | |
HR | 홈런 | 홈런 | |
TB | 루타 | ||
RBI | 타점 | 타점 | |
SB | 도루 성공 | 도루 성공 | |
CS | 도루 실패 | 도루 실패 | |
BB | 볼넷 | 볼넷 | |
HBP | 사구 | 사구 | |
SO | 삼진 | 삼진 | |
GDP | 병살 | 병살 | |
SLG | 장타율 | ||
OBP | 출루율 | ||
E | 실책 | ||
height/weight | 선수 키/몸무게 | ||
year_born | 생년월일 | ||
position | 수비 위치 | ||
career | 커리어 | ||
starting_salary | 입단 연봉 | ||
OPS | (OBP+SLG) | 예측 OPS | |
date | 날짜 | ||
opposing_team | 상대 팀 |
In [271]:
pd.read_csv('./datas/Regular_Season_Batter_Day_by_Day_b4.csv').head()
Out[271]:
batter_id | batter_name | date | opposing_team | avg1 | AB | R | H | 2B | 3B | HR | RBI | SB | CS | BB | HBP | SO | GDP | avg2 | year | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 0 | 가르시아 | 3.24 | NC | 0.333 | 3 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 0.333 | 2018 |
1 | 0 | 가르시아 | 3.25 | NC | 0.000 | 4 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0.143 | 2018 |
2 | 0 | 가르시아 | 3.27 | 넥센 | 0.200 | 5 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0.167 | 2018 |
3 | 0 | 가르시아 | 3.28 | 넥센 | 0.200 | 5 | 1 | 1 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0.176 | 2018 |
4 | 0 | 가르시아 | 3.29 | 넥센 | 0.250 | 4 | 0 | 1 | 0 | 0 | 0 | 3 | 0 | 0 | 0 | 0 | 0 | 1 | 0.190 | 2018 |
In [272]:
pd.read_csv('./datas/Pre_Season_Batter.csv').head(1)
Out[272]:
batter_id | batter_name | year | team | avg | G | AB | R | H | 2B | 3B | HR | TB | RBI | SB | CS | BB | HBP | SO | GDP | SLG | OBP | E | height/weight | year_born | position | career | starting_salary | OPS | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 0 | 가르시아 | 2018 | LG | 0.350 | 7 | 20 | 1 | 7 | 1 | 0 | 1 | 11 | 5 | 0 | 0 | 2 | 0 | 3 | 1 | 0.55 | 0.409 | 1 | 177cm/93kg | 1985년 04월 12일 | 내야수(우투우타) | 쿠바 Ciego de Avila Maximo Gomez Baez(대) | NaN | 0.959 |
In [273]:
pd.read_csv('./datas/Regular_Season_Batter.csv').head(1)
Out[273]:
batter_id | batter_name | year | team | avg | G | AB | R | H | 2B | 3B | HR | TB | RBI | SB | CS | BB | HBP | SO | GDP | SLG | OBP | E | height/weight | year_born | position | career | starting_salary | OPS | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 0 | 가르시아 | 2018 | LG | 0.339 | 50 | 183 | 27 | 62 | 9 | 0 | 8 | 95 | 34 | 5 | 0 | 9 | 8 | 25 | 3 | 0.519 | 0.383 | 9 | 177cm/93kg | 1985년 04월 12일 | 내야수(우투우타) | 쿠바 Ciego de Avila Maximo Gomez Baez(대) | NaN | 0.902 |
In [274]:
pd.read_csv('./datas/submission.csv').head()
Out[274]:
batter_id | batter_name | |
---|---|---|
0 | 1 | 강경학 |
1 | 2 | 강구성 |
2 | 3 | 강민국 |
3 | 4 | 강민호 |
4 | 5 | 강백호 |
프리시즌 데이터 확인¶
In [275]:
preseason = pd.read_csv('./datas/Pre_Season_Batter.csv')
print(preseason.shape)
print()
print(preseason.info())
preseason.head()
(1393, 29) <class 'pandas.core.frame.DataFrame'> RangeIndex: 1393 entries, 0 to 1392 Data columns (total 29 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 batter_id 1393 non-null int64 1 batter_name 1393 non-null object 2 year 1393 non-null int64 3 team 1393 non-null object 4 avg 1393 non-null object 5 G 1393 non-null int64 6 AB 1393 non-null int64 7 R 1393 non-null int64 8 H 1393 non-null int64 9 2B 1393 non-null int64 10 3B 1393 non-null int64 11 HR 1393 non-null int64 12 TB 1393 non-null int64 13 RBI 1393 non-null int64 14 SB 1393 non-null int64 15 CS 1393 non-null int64 16 BB 1393 non-null int64 17 HBP 1393 non-null int64 18 SO 1393 non-null int64 19 GDP 1393 non-null int64 20 SLG 1364 non-null float64 21 OBP 1368 non-null float64 22 E 1393 non-null int64 23 height/weight 1393 non-null object 24 year_born 1393 non-null object 25 position 1393 non-null object 26 career 1393 non-null object 27 starting_salary 1179 non-null object 28 OPS 1364 non-null float64 dtypes: float64(3), int64(18), object(8) memory usage: 315.7+ KB None
Out[275]:
batter_id | batter_name | year | team | avg | G | AB | R | H | 2B | 3B | HR | TB | RBI | SB | CS | BB | HBP | SO | GDP | SLG | OBP | E | height/weight | year_born | position | career | starting_salary | OPS | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 0 | 가르시아 | 2018 | LG | 0.350 | 7 | 20 | 1 | 7 | 1 | 0 | 1 | 11 | 5 | 0 | 0 | 2 | 0 | 3 | 1 | 0.550 | 0.409 | 1 | 177cm/93kg | 1985년 04월 12일 | 내야수(우투우타) | 쿠바 Ciego de Avila Maximo Gomez Baez(대) | NaN | 0.959 |
1 | 1 | 강경학 | 2011 | 한화 | 0.000 | 4 | 2 | 2 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 2 | 1 | 0 | 0.000 | 0.500 | 0 | 180cm/72kg | 1992년 08월 11일 | 내야수(우투좌타) | 광주대성초-광주동성중-광주동성고 | 10000만원 | 0.500 |
2 | 1 | 강경학 | 2014 | 한화 | - | 4 | 0 | 2 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | NaN | NaN | 0 | 180cm/72kg | 1992년 08월 11일 | 내야수(우투좌타) | 광주대성초-광주동성중-광주동성고 | 10000만원 | NaN |
3 | 1 | 강경학 | 2015 | 한화 | 0.130 | 10 | 23 | 3 | 3 | 0 | 0 | 0 | 3 | 1 | 3 | 0 | 4 | 1 | 9 | 0 | 0.130 | 0.286 | 2 | 180cm/72kg | 1992년 08월 11일 | 내야수(우투좌타) | 광주대성초-광주동성중-광주동성고 | 10000만원 | 0.416 |
4 | 1 | 강경학 | 2016 | 한화 | 0.188 | 14 | 32 | 4 | 6 | 1 | 1 | 0 | 9 | 2 | 1 | 2 | 0 | 1 | 10 | 0 | 0.281 | 0.212 | 0 | 180cm/72kg | 1992년 08월 11일 | 내야수(우투좌타) | 광주대성초-광주동성중-광주동성고 | 10000만원 | 0.493 |
In [276]:
# 데이터 기초 통계량
'''
1. 선수는 총 344명이 있다.
2. 데이터는 2002년부터 2018년까지 존재한다.
'''
preseason.describe()
Out[276]:
batter_id | year | G | AB | R | H | 2B | 3B | HR | TB | RBI | SB | CS | BB | HBP | SO | GDP | SLG | OBP | E | OPS | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
count | 1393.000000 | 1393.000000 | 1393.000000 | 1393.000000 | 1393.000000 | 1393.000000 | 1393.000000 | 1393.000000 | 1393.000000 | 1393.000000 | 1393.000000 | 1393.000000 | 1393.000000 | 1393.000000 | 1393.000000 | 1393.000000 | 1393.000000 | 1364.000000 | 1368.000000 | 1393.000000 | 1364.000000 |
mean | 173.434314 | 2013.014358 | 8.705671 | 19.201723 | 2.679828 | 5.021536 | 0.954774 | 0.119885 | 0.391960 | 7.391960 | 2.430725 | 0.629576 | 0.291457 | 1.877961 | 0.330223 | 3.714286 | 0.447236 | 0.361012 | 0.317912 | 0.381910 | 0.676924 |
std | 94.716851 | 4.166757 | 5.562686 | 13.395946 | 2.637212 | 4.232584 | 1.196904 | 0.379976 | 0.748557 | 6.538787 | 2.698122 | 1.146854 | 0.595522 | 2.053392 | 0.642204 | 3.180884 | 0.723364 | 0.269892 | 0.151489 | 0.729521 | 0.386933 |
min | 0.000000 | 2002.000000 | 1.000000 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 0.000000 |
25% | 99.000000 | 2010.000000 | 6.000000 | 9.000000 | 1.000000 | 2.000000 | 0.000000 | 0.000000 | 0.000000 | 2.000000 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 1.000000 | 0.000000 | 0.217000 | 0.250000 | 0.000000 | 0.472000 |
50% | 178.000000 | 2014.000000 | 9.000000 | 18.000000 | 2.000000 | 4.000000 | 1.000000 | 0.000000 | 0.000000 | 6.000000 | 2.000000 | 0.000000 | 0.000000 | 1.000000 | 0.000000 | 3.000000 | 0.000000 | 0.344500 | 0.333000 | 0.000000 | 0.675000 |
75% | 254.000000 | 2017.000000 | 11.000000 | 28.000000 | 4.000000 | 8.000000 | 2.000000 | 0.000000 | 1.000000 | 11.000000 | 4.000000 | 1.000000 | 0.000000 | 3.000000 | 1.000000 | 5.000000 | 1.000000 | 0.478000 | 0.400000 | 1.000000 | 0.867000 |
max | 344.000000 | 2018.000000 | 119.000000 | 183.000000 | 35.000000 | 51.000000 | 11.000000 | 4.000000 | 5.000000 | 68.000000 | 24.000000 | 9.000000 | 4.000000 | 21.000000 | 4.000000 | 36.000000 | 5.000000 | 4.000000 | 1.000000 | 5.000000 | 5.000000 |
In [277]:
'''
프리시즌은 연습경기이기 때문에 많은 데이터가 0쪽에 가깝다.
예를 들어 1년에 일반적인 정규타석을 채우지 않았고, 득전, 타수, 안타 등이 0에 가깝다.
또한 데이터의 양은 과거보다 최근에 가까워 질수록 많아진다.
'''
preseason.hist(figsize=(20,9))
plt.tight_layout()
plt.show()
In [278]:
'''
데이터의 개수가 적어서 그런가 대부분의 연도의 OPS의 평균이 비슷하다.
'''
plt.figure(figsize=(20,5))
sns.boxplot(x='year', y='OPS', data=preseason, showfliers=False)
Out[278]:
<Axes: xlabel='year', ylabel='OPS'>
In [279]:
'''
몇 몇 선수들을 추출해 OPS를 비교해 보았다.
그러던 도중 결측값이 있는 것을 발견하였다.
'''
preseason_df_2002 = preseason[preseason['year'] == 2002]
preseason_df_2002
Out[279]:
batter_id | batter_name | year | team | avg | G | AB | R | H | 2B | 3B | HR | TB | RBI | SB | CS | BB | HBP | SO | GDP | SLG | OBP | E | height/weight | year_born | position | career | starting_salary | OPS | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
228 | 62 | 김주찬 | 2002 | 롯데 | 0.107 | 9 | 28 | 2 | 3 | 0 | 0 | 0 | 3 | 0 | 2 | 0 | 1 | 1 | 7 | 1 | 0.107 | 0.167 | 1 | 183cm/94kg | 1981년 03월 25일 | 내야수(우투우타) | 충암초(장충리틀)-충암중-충암고-삼성-롯데 | 18000만원 | 0.274 |
260 | 67 | 김태균 | 2002 | 한화 | 0.235 | 11 | 34 | 7 | 8 | 5 | 0 | 1 | 16 | 4 | 1 | 0 | 4 | 1 | 14 | 0 | 0.471 | 0.333 | 2 | 185cm/110kg | 1982년 05월 29일 | 내야수(우투우타) | 천안남산초-천안북중-북일고-(대전대) | 16000만원 | 0.804 |
413 | 109 | 박기혁 | 2002 | 롯데 | 0.000 | 8 | 5 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 4 | 0 | 0.000 | 0.000 | 0 | 179cm/77kg | 1981년 06월 04일 | 내야수(우투우타) | 대구수창초-성광중-대구상고-롯데 | 8000만원 | 0.000 |
467 | 119 | 박용택 | 2002 | LG | - | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | NaN | NaN | 0 | 185cm/90kg | 1979년 04월 21일 | 외야수(우투좌타) | 고명초-휘문중-휘문고-고려대 | 30000만원 | NaN |
511 | 131 | 박한이 | 2002 | 삼성 | 0.319 | 11 | 47 | 7 | 15 | 3 | 0 | 1 | 21 | 4 | 3 | 0 | 3 | 0 | 8 | 1 | 0.447 | 0.360 | 0 | 182cm/91kg | 1979년 01월 28일 | 외야수(좌투좌타) | 초량초-부산중-부산고-동국대 | 30000만원 | 0.807 |
824 | 202 | 이대호 | 2002 | 롯데 | 0.359 | 11 | 39 | 4 | 14 | 3 | 0 | 1 | 20 | 4 | 0 | 0 | 1 | 0 | 8 | 1 | 0.513 | 0.375 | 1 | 194cm/130kg | 1982년 06월 21일 | 내야수(우투우타) | 부산수영초-대동중-경남고-(영남사이버대)-롯데-시애틀 | 21000만원 | 0.888 |
844 | 207 | 이범호 | 2002 | 한화 | 0.167 | 7 | 6 | 2 | 1 | 1 | 0 | 0 | 2 | 2 | 0 | 0 | 0 | 0 | 1 | 0 | 0.333 | 0.167 | 0 | 183cm/96kg | 1981년 11월 25일 | 내야수(우투우타) | 대구수창초-경운중-대구고-한화 | 11000만원 | 0.500 |
892 | 283 | 조동찬 | 2002 | 삼성 | 0.000 | 4 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0.000 | 0.000 | 0 | 180cm/80kg | 1983년 07월 27일 | 내야수(우투우타) | 공주중동초-공주중-공주고 | 12000만원 | 0.000 |
984 | 234 | 이진영 | 2002 | SK | 0.297 | 11 | 37 | 5 | 11 | 2 | 0 | 2 | 19 | 6 | 2 | 2 | 5 | 0 | 12 | 0 | 0.514 | 0.381 | 0 | 185cm/90kg | 1980년 06월 15일 | 외야수(좌투좌타) | 군산초-군산남중-군산상고-쌍방울-SK-LG | 10000만원 | 0.895 |
1115 | 269 | 정상호 | 2002 | SK | 0.158 | 13 | 19 | 3 | 3 | 1 | 0 | 1 | 7 | 2 | 0 | 0 | 3 | 1 | 5 | 0 | 0.368 | 0.304 | 5 | 187cm/100kg | 1982년 12월 24일 | 포수(우투우타) | 석천초-동인천중-동산고-SK-상무-SK | 45000만원 | 0.672 |
1128 | 270 | 정성훈 | 2002 | KIA | 0.267 | 12 | 30 | 5 | 8 | 4 | 0 | 0 | 12 | 4 | 0 | 0 | 0 | 0 | 3 | 1 | 0.400 | 0.258 | 0 | 182cm/83kg | 1980년 06월 27일 | 내야수(우투우타) | 송정동초-무등중-광주제일고-해태-KIA-현대-우리-LG | 15000만원 | 0.658 |
1327 | 319 | 최형우 | 2002 | 삼성 | 0.000 | 5 | 5 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0.000 | 0.167 | 0 | 180cm/106kg | 1983년 12월 16일 | 외야수(우투좌타) | 진북초-전주동중-전주고-삼성-경찰-삼성 | 5000만원 | 0.167 |
In [280]:
'''
결측값의 개수를 확인해 보았다.
'''
for i, j in preseason.isnull().sum().items():
if not j == 0:
print(i, j)
'''
nan 값이 있는 행만 추출해 보았다.
그 중에서 starting_salary부분이 nan인 경우는 제외 하였다.
'''
preseason[preseason.isna().any(axis=1) & preseason['starting_salary'].notna()].head()
SLG 29 OBP 25 starting_salary 214 OPS 29
Out[280]:
batter_id | batter_name | year | team | avg | G | AB | R | H | 2B | 3B | HR | TB | RBI | SB | CS | BB | HBP | SO | GDP | SLG | OBP | E | height/weight | year_born | position | career | starting_salary | OPS | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
2 | 1 | 강경학 | 2014 | 한화 | - | 4 | 0 | 2 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | NaN | NaN | 0 | 180cm/72kg | 1992년 08월 11일 | 내야수(우투좌타) | 광주대성초-광주동성중-광주동성고 | 10000만원 | NaN |
37 | 8 | 강상원 | 2016 | 한화 | - | 6 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 2 | 1 | 0 | 0 | 0 | 0 | NaN | NaN | 0 | 172cm/64kg | 1997년 05월 05일 | 외야수(우투좌타) | 온양온천초-온양중-북일고 | 3000만원 | NaN |
74 | 24 | 김강민 | 2003 | SK | - | 3 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | NaN | NaN | 0 | 182cm/85kg | 1982년 09월 13일 | 외야수(우투우타) | 본리초-대구중-경북고 | 11000만원 | NaN |
80 | 24 | 김강민 | 2009 | SK | - | 2 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | NaN | NaN | 0 | 182cm/85kg | 1982년 09월 13일 | 외야수(우투우타) | 본리초-대구중-경북고 | 11000만원 | NaN |
90 | 101 | 문선재 | 2009 | LG | - | 2 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | NaN | 1.0 | 0 | 184cm/80kg | 1990년 05월 20일 | 외야수(우투우타) | 광주서림초-광주동성중-광주동성고-LG-상무 | 5000만원 | NaN |
In [281]:
'''
장타율과 출루율이 계산되지 않아 OPS가 NaN이 나온것을 확인 하였다.
검색해 보니 장타율 같은 경우에는 (3루타 + 2루타 + 홈런) / 안타 로 계산하는데 이것은 TBS식 장타율이라고 한다.
다른 데이터와 비교하여 TBS식 장타율로 계산되었으면 이것도 같은 방법으로 계산하여 채우려고 한다.
'''
# 3루타, 2루타, 홈런, 안타를 추출하여 계산
print(f'clac_SLG: {preseason.loc[0, ["3B", "2B", "HR"]].sum() / preseason.loc[0, ["H"]]}')
print(f'orig_SLG: {preseason.loc[0, "SLG"]}')
print()
'''
계산해 보니 다르다.
알고보니 이것은 일본 TBS 테레비의 루즈밸트 게임 드라마에서 나온 잘못된 계산식이라고 한다.
조금 더 찾아보니 다른 식을 찾을 수 있었다.
(1루타(단타) x 1 + 2루타 x 2 + 3루타 x 3 + 홈런 x 4) / 타수
'''
# 안타, 2루타, 3루타, 홈런을 추출하여 각각 1, 2, 3, 4씩 곱하고 이후 타수만큼 나눈다.
cnt = 1
SLG = 0
for i in preseason.loc[0, ['H', '2B', '3B', 'HR']]:
SLG += i * cnt
cnt += 1
SLG = SLG / preseason.loc[0, "AB"]
print(f'clac_SLG: {SLG}')
print(f'orig_SLG: {preseason.loc[0, "SLG"]}')
print()
'''
약 0.1 정도의 오차가 발생하였다.
어디서 잘못 되었나 좀 더 찾아보니
단타는 총 안타에서 2, 3루타 그리고 홈런을 제외한 숫자를 의미한다.
그러면 단타는 안타의 개수는 7이 아니라 2루타와 홈런을 제외한 5가 된다.
이것을 기반으로 다시 계산하였다.
'''
H = preseason.loc[0, 'H'] - preseason.loc[0, ['2B', '3B', 'HR']].sum()
cnt = 2
SLG = H
for i in preseason.loc[0, ['2B', '3B', 'HR']]:
SLG += i * cnt
cnt += 1
SLG = SLG / preseason.loc[0, "AB"]
print(f'clac_SLG: {SLG}')
print(f'orig_SLG: {preseason.loc[0, "SLG"]}')
clac_SLG: H 0.285714 Name: 0, dtype: object orig_SLG: 0.55 clac_SLG: 0.65 orig_SLG: 0.55 clac_SLG: 0.55 orig_SLG: 0.55
In [282]:
'''
이제 저 계산식을 기반으로 NaN 값을 채우려고 한다.
이제 SLG는 다 채웠으니 OBP만 채우면 된다.
'''
def SLG_calc(row):
# SLG가 NaN이 아닐 경우 그대로 반환
if pd.notna(row['SLG']):
return row['SLG']
# 타수가 없는 경우
if pd.notna(row['AB']) or row['AB'] == 0:
return 0
H = row['H'] - row[['2B', '3B', 'HR']].sum()
SLG = (H + row['2B'] * 2 + row['3B'] * 3 + row['HR'] * 4) / row['AB']
return SLG
display(preseason.head())
print()
preseason['SLG'] = preseason.apply(SLG_calc, axis=1)
display(preseason.head())
for i, j in preseason.isnull().sum().items():
if not j == 0:
print(i, j)
batter_id | batter_name | year | team | avg | G | AB | R | H | 2B | 3B | HR | TB | RBI | SB | CS | BB | HBP | SO | GDP | SLG | OBP | E | height/weight | year_born | position | career | starting_salary | OPS | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 0 | 가르시아 | 2018 | LG | 0.350 | 7 | 20 | 1 | 7 | 1 | 0 | 1 | 11 | 5 | 0 | 0 | 2 | 0 | 3 | 1 | 0.550 | 0.409 | 1 | 177cm/93kg | 1985년 04월 12일 | 내야수(우투우타) | 쿠바 Ciego de Avila Maximo Gomez Baez(대) | NaN | 0.959 |
1 | 1 | 강경학 | 2011 | 한화 | 0.000 | 4 | 2 | 2 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 2 | 1 | 0 | 0.000 | 0.500 | 0 | 180cm/72kg | 1992년 08월 11일 | 내야수(우투좌타) | 광주대성초-광주동성중-광주동성고 | 10000만원 | 0.500 |
2 | 1 | 강경학 | 2014 | 한화 | - | 4 | 0 | 2 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | NaN | NaN | 0 | 180cm/72kg | 1992년 08월 11일 | 내야수(우투좌타) | 광주대성초-광주동성중-광주동성고 | 10000만원 | NaN |
3 | 1 | 강경학 | 2015 | 한화 | 0.130 | 10 | 23 | 3 | 3 | 0 | 0 | 0 | 3 | 1 | 3 | 0 | 4 | 1 | 9 | 0 | 0.130 | 0.286 | 2 | 180cm/72kg | 1992년 08월 11일 | 내야수(우투좌타) | 광주대성초-광주동성중-광주동성고 | 10000만원 | 0.416 |
4 | 1 | 강경학 | 2016 | 한화 | 0.188 | 14 | 32 | 4 | 6 | 1 | 1 | 0 | 9 | 2 | 1 | 2 | 0 | 1 | 10 | 0 | 0.281 | 0.212 | 0 | 180cm/72kg | 1992년 08월 11일 | 내야수(우투좌타) | 광주대성초-광주동성중-광주동성고 | 10000만원 | 0.493 |
batter_id | batter_name | year | team | avg | G | AB | R | H | 2B | 3B | HR | TB | RBI | SB | CS | BB | HBP | SO | GDP | SLG | OBP | E | height/weight | year_born | position | career | starting_salary | OPS | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 0 | 가르시아 | 2018 | LG | 0.350 | 7 | 20 | 1 | 7 | 1 | 0 | 1 | 11 | 5 | 0 | 0 | 2 | 0 | 3 | 1 | 0.550 | 0.409 | 1 | 177cm/93kg | 1985년 04월 12일 | 내야수(우투우타) | 쿠바 Ciego de Avila Maximo Gomez Baez(대) | NaN | 0.959 |
1 | 1 | 강경학 | 2011 | 한화 | 0.000 | 4 | 2 | 2 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 2 | 1 | 0 | 0.000 | 0.500 | 0 | 180cm/72kg | 1992년 08월 11일 | 내야수(우투좌타) | 광주대성초-광주동성중-광주동성고 | 10000만원 | 0.500 |
2 | 1 | 강경학 | 2014 | 한화 | - | 4 | 0 | 2 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0.000 | NaN | 0 | 180cm/72kg | 1992년 08월 11일 | 내야수(우투좌타) | 광주대성초-광주동성중-광주동성고 | 10000만원 | NaN |
3 | 1 | 강경학 | 2015 | 한화 | 0.130 | 10 | 23 | 3 | 3 | 0 | 0 | 0 | 3 | 1 | 3 | 0 | 4 | 1 | 9 | 0 | 0.130 | 0.286 | 2 | 180cm/72kg | 1992년 08월 11일 | 내야수(우투좌타) | 광주대성초-광주동성중-광주동성고 | 10000만원 | 0.416 |
4 | 1 | 강경학 | 2016 | 한화 | 0.188 | 14 | 32 | 4 | 6 | 1 | 1 | 0 | 9 | 2 | 1 | 2 | 0 | 1 | 10 | 0 | 0.281 | 0.212 | 0 | 180cm/72kg | 1992년 08월 11일 | 내야수(우투좌타) | 광주대성초-광주동성중-광주동성고 | 10000만원 | 0.493 |
OBP 25 starting_salary 214 OPS 29
In [283]:
'''
출루율의 계산 공식은 아래와 같다.
(안타 + 볼넷 + 사구) / (타수 + 볼넷 + 사구 + 희생 플라이)
하지만 주어진 데이터에는 희생 플라이는 존재하지 않는다.
그렇기 때문에 일단 0으로 두고 계산해 보았다.
이것으로 한 번 계산해 보았다.
'''
print(f'clac_OPS: {preseason.loc[0, ["H", "BB", "HBP"]].sum() / preseason.loc[0, ["AB", "BB", "HBP"]].sum()}')
print(f'orig_OPS: {preseason.loc[0, ["OBP"]]}')
'''
제대로 된 계산식임을 확인 하였기에 위와 똑같이 채워 주었다.
'''
def OBP_calc(row):
# OBP가 NaN이 아닐 경우 그대로 반환
if pd.notna(row['OBP']):
return row['OBP']
denominator = row[['H', 'BB', 'HBP']].sum()
numerator = row[['AB', 'BB', 'HBP']].sum()
# 분모 또는 분자가 0 인경우
if denominator == 0 or numerator == 0:
return 0
OBP = denominator / numerator
return OBP
preseason['OBP'] = preseason.apply(OBP_calc, axis=1)
display(preseason.head())
for i, j in preseason.isnull().sum().items():
if not j == 0:
print(i, j)
clac_OPS: 0.4090909090909091 orig_OPS: OBP 0.409 Name: 0, dtype: object
batter_id | batter_name | year | team | avg | G | AB | R | H | 2B | 3B | HR | TB | RBI | SB | CS | BB | HBP | SO | GDP | SLG | OBP | E | height/weight | year_born | position | career | starting_salary | OPS | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 0 | 가르시아 | 2018 | LG | 0.350 | 7 | 20 | 1 | 7 | 1 | 0 | 1 | 11 | 5 | 0 | 0 | 2 | 0 | 3 | 1 | 0.550 | 0.409 | 1 | 177cm/93kg | 1985년 04월 12일 | 내야수(우투우타) | 쿠바 Ciego de Avila Maximo Gomez Baez(대) | NaN | 0.959 |
1 | 1 | 강경학 | 2011 | 한화 | 0.000 | 4 | 2 | 2 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 2 | 1 | 0 | 0.000 | 0.500 | 0 | 180cm/72kg | 1992년 08월 11일 | 내야수(우투좌타) | 광주대성초-광주동성중-광주동성고 | 10000만원 | 0.500 |
2 | 1 | 강경학 | 2014 | 한화 | - | 4 | 0 | 2 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0.000 | 0.000 | 0 | 180cm/72kg | 1992년 08월 11일 | 내야수(우투좌타) | 광주대성초-광주동성중-광주동성고 | 10000만원 | NaN |
3 | 1 | 강경학 | 2015 | 한화 | 0.130 | 10 | 23 | 3 | 3 | 0 | 0 | 0 | 3 | 1 | 3 | 0 | 4 | 1 | 9 | 0 | 0.130 | 0.286 | 2 | 180cm/72kg | 1992년 08월 11일 | 내야수(우투좌타) | 광주대성초-광주동성중-광주동성고 | 10000만원 | 0.416 |
4 | 1 | 강경학 | 2016 | 한화 | 0.188 | 14 | 32 | 4 | 6 | 1 | 1 | 0 | 9 | 2 | 1 | 2 | 0 | 1 | 10 | 0 | 0.281 | 0.212 | 0 | 180cm/72kg | 1992년 08월 11일 | 내야수(우투좌타) | 광주대성초-광주동성중-광주동성고 | 10000만원 | 0.493 |
starting_salary 214 OPS 29
In [286]:
# OPS 계산
# OPS = SLG + OPB
def OPS_clac(row):
return row[['SLG', 'OBP']].sum()
preseason['OPS'] = preseason.apply(OPS_clac, axis=1)
display(preseason)
for i, j in preseason.isnull().sum().items():
if not j == 0:
print(i, j)
batter_id | batter_name | year | team | avg | G | AB | R | H | 2B | 3B | HR | TB | RBI | SB | CS | BB | HBP | SO | GDP | SLG | OBP | E | height/weight | year_born | position | career | starting_salary | OPS | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 0 | 가르시아 | 2018 | LG | 0.350 | 7 | 20 | 1 | 7 | 1 | 0 | 1 | 11 | 5 | 0 | 0 | 2 | 0 | 3 | 1 | 0.550 | 0.409 | 1 | 177cm/93kg | 1985년 04월 12일 | 내야수(우투우타) | 쿠바 Ciego de Avila Maximo Gomez Baez(대) | NaN | 0.959 |
1 | 1 | 강경학 | 2011 | 한화 | 0.000 | 4 | 2 | 2 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 2 | 1 | 0 | 0.000 | 0.500 | 0 | 180cm/72kg | 1992년 08월 11일 | 내야수(우투좌타) | 광주대성초-광주동성중-광주동성고 | 10000만원 | 0.500 |
2 | 1 | 강경학 | 2014 | 한화 | - | 4 | 0 | 2 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0.000 | 0.000 | 0 | 180cm/72kg | 1992년 08월 11일 | 내야수(우투좌타) | 광주대성초-광주동성중-광주동성고 | 10000만원 | 0.000 |
3 | 1 | 강경학 | 2015 | 한화 | 0.130 | 10 | 23 | 3 | 3 | 0 | 0 | 0 | 3 | 1 | 3 | 0 | 4 | 1 | 9 | 0 | 0.130 | 0.286 | 2 | 180cm/72kg | 1992년 08월 11일 | 내야수(우투좌타) | 광주대성초-광주동성중-광주동성고 | 10000만원 | 0.416 |
4 | 1 | 강경학 | 2016 | 한화 | 0.188 | 14 | 32 | 4 | 6 | 1 | 1 | 0 | 9 | 2 | 1 | 2 | 0 | 1 | 10 | 0 | 0.281 | 0.212 | 0 | 180cm/72kg | 1992년 08월 11일 | 내야수(우투좌타) | 광주대성초-광주동성중-광주동성고 | 10000만원 | 0.493 |
... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
1388 | 342 | 황재균 | 2014 | 롯데 | 0.407 | 10 | 27 | 3 | 11 | 2 | 0 | 1 | 16 | 4 | 1 | 0 | 2 | 0 | 5 | 0 | 0.593 | 0.448 | 1 | 183cm/96kg | 1987년 07월 28일 | 내야수(우투우타) | 사당초-이수중-경기고-현대-우리-히어로즈-넥센-롯데-샌프란시스코 | 6000만원 | 1.041 |
1389 | 342 | 황재균 | 2015 | 롯데 | 0.333 | 11 | 30 | 8 | 10 | 3 | 0 | 0 | 13 | 6 | 0 | 0 | 4 | 0 | 3 | 0 | 0.433 | 0.389 | 0 | 183cm/96kg | 1987년 07월 28일 | 내야수(우투우타) | 사당초-이수중-경기고-현대-우리-히어로즈-넥센-롯데-샌프란시스코 | 6000만원 | 0.822 |
1390 | 342 | 황재균 | 2016 | 롯데 | 0.310 | 16 | 42 | 8 | 13 | 3 | 1 | 0 | 18 | 4 | 3 | 1 | 4 | 0 | 4 | 0 | 0.429 | 0.370 | 1 | 183cm/96kg | 1987년 07월 28일 | 내야수(우투우타) | 사당초-이수중-경기고-현대-우리-히어로즈-넥센-롯데-샌프란시스코 | 6000만원 | 0.799 |
1391 | 342 | 황재균 | 2018 | KT | 0.250 | 6 | 16 | 3 | 4 | 1 | 0 | 1 | 8 | 4 | 0 | 0 | 2 | 0 | 6 | 0 | 0.500 | 0.333 | 3 | 183cm/96kg | 1987년 07월 28일 | 내야수(우투우타) | 사당초-이수중-경기고-현대-우리-히어로즈-넥센-롯데-샌프란시스코 | 6000만원 | 0.833 |
1392 | 344 | 황진수 | 2014 | 롯데 | 0.000 | 1 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0.000 | 0.000 | 0 | 181cm/82kg | 1989년 02월 15일 | 내야수(우투양타) | 석천초-대헌중-공주고 | 4000만원 | 0.000 |
1393 rows × 29 columns
starting_salary 214
In [ ]:
반응형
'아무거나 만들어 봄 > KBO 타자 OPS 예측 경진대회' 카테고리의 다른 글
KBO 타자 OPS 예측 경연대회 - 5 (0) | 2024.12.03 |
---|---|
KBO 타자 OPS 예측 경연대회 - 4 (0) | 2024.12.03 |
KBO 타자 OPS 예측 경연대회 - 3 (0) | 2024.12.03 |
KBO 타자 OPS 예측 경연대회 - 2 (0) | 2024.12.01 |
KBO 타자 OPS 예측 경진대회 - 개요 (0) | 2024.11.30 |