λŸ¬λ‹μŠ€ν‘Όμ¦ˆ μˆ˜μ—… 정리 

 

 

< 이전 κΈ€ > 

https://silvercoding.tistory.com/53

 

[python μ‹œκ°ν™”] 2. μ„œμšΈμ‹œ λŒ€ν”Όμ†Œ ν˜„ν™© 지도 λ§Œλ“€κΈ° , 지도 μ‹œκ°ν™” ( folium 라이브러리 )

λŸ¬λ‹μŠ€ν‘Όμ¦ˆ μˆ˜μ—… 정리 < 이전 κΈ€ > https://silvercoding.tistory.com/52 [python μ‹œκ°ν™”] 1. seaborn 라이브러리 (distplot, relplot, jointplot, pairplot, boxplot, swarmplot, heatmap) λŸ¬λ‹μŠ€ν‘Ό μˆ˜μ—… μ •λ¦¬..

silvercoding.tistory.com

 

 


 μ‚¬μ „ 지식 
  • νƒ€μœ¨ : 타격에 성곡해 μ‚΄μ•„λ‚˜κ°€λŠ” 정도 

= 타격 성곡 횟수 / 타격 기회 수 

= μ•ˆνƒ€ 수 / νƒ€μˆ˜ 

  • 좜루율 : μ‚΄μ•„μ„œ λ‚˜κ°€λŠ” 정도 

= 진루 성곡 횟수 / 진루 기회 수 

= (μ•ˆνƒ€+λ³Όλ„·+λͺΈμ— λ§žλŠ” λ³Ό) / (νƒ€μˆ˜+λ³Όλ„·+λͺΈμ— λ§žλŠ” λ³Ό+희생 ν”ŒλΌμ΄) 

  • μž₯νƒ€μœ¨ : 타격에 성곡해 멀리 μ‚΄μ•„λ‚˜κ°€λŠ” 정도 

= μ§„λ£¨ν•œ 베이슀 수 / 타격 기회 수 

= 루타 수 / νƒ€μˆ˜ 

(νƒ€μœ¨μ— 거리 κ°œλ… μΆ”κ°€ : 2루타 = 1루타 x 2) 

  • OPS  : μ‚΄μ•„μ„œ 멀리 λ‚˜κ°€λŠ” 정도   

= 좜루율 + μž₯νƒ€μœ¨ 

 

 

 

*** λ³Έ 기초 μ‹œκ°ν™” ν”„λ‘œμ νŠΈμ—μ„œλŠ” 좜루율 - μž₯νƒ€μœ¨ - ops - νƒ€μœ¨ 을 κΈ°μ€€μœΌλ‘œ best player λ₯Ό λΆ„μ„ν•œλ‹€. ***

 

 

 

 


 λ°μ΄ν„° 뢈러였기 & μ‚΄νŽ΄λ³΄κΈ° 
import pandas as pd
file  = './data/KBO_2019_player_gamestats.csv'
raw = pd.read_csv(file, encoding = 'cp949')

데이터 : KBO 2019 μ‹œμ¦Œ νƒ€μž 기둝지 데이터 (λŸ¬λ‹μŠ€ν‘Όμ¦ˆ 제곡) 

raw.head()

νƒ€μž & κ²Œμž„ λ³„λ‘œ κΈ°λ‘λ˜μ–΄ μžˆλ‹€. 

raw.info()

raw.columns

μ‚¬μš©ν•  μ»¬λŸΌμ„ 뽑기 μœ„ν•΄ 전체 μ»¬λŸΌμ„ μ‚΄νŽ΄ λ³Έλ‹€. 

columns_select = ['νŒ€', '이름', '생일','일자', 'μƒλŒ€','νƒ€μˆ˜','μ•ˆνƒ€','ν™ˆλŸ°', '루타', '타점','λ³Όλ„·', '사ꡬ', '희비']
data = raw[columns_select]
data.head()

μ›ν•˜λŠ” 컬럼만 λ½‘μ•„μ„œ DataFrame을 μƒμ„±ν•˜κ³ , data에 λ„£μ–΄μ£Όμ—ˆλ‹€. 

 

 

 

 

 


 KBO best player λΆ„μ„ν•˜κΈ° 

- μ„ μˆ˜λ³„ 기둝 집계 

data_player = data.pivot_table(index = ['νŒ€','이름','생일'], 
                               values = ['νƒ€μˆ˜','μ•ˆνƒ€','ν™ˆλŸ°','루타','타점','λ³Όλ„·','사ꡬ','희비'], 
                              aggfunc = 'sum')

data_player

pivot_table 을 μ‚¬μš©ν•˜μ—¬ νŒ€, 이름 , 생일을 κΈ°μ€€μœΌλ‘œ νƒ€μˆ˜, μ•ˆνƒ€, ν™ˆλŸ°, 루타, 타점, λ³Όλ„·, 사ꡬ, ν¬λΉ„μ˜ 총 합계λ₯Ό μ§‘κ³„ν•œλ‹€. 

data_player['νƒ€μˆ˜'].hist()

νŒλ‹€μŠ€μ—μ„œ 기본으둜 λ‚΄μž₯λ˜μ–΄ μžˆλŠ” μ‹œλ¦¬μ¦ˆ.hist()λ₯Ό μ‚¬μš©ν•˜μ—¬ νƒ€μˆ˜μ˜ 뢄포 μ‚΄νŽ΄λ³΄κΈ° . ( νƒ€μˆ˜κ°€ 적은 μ„ μˆ˜λ₯Ό μ œμ™Έν•˜κΈ° μœ„ν•΄ μ–΄λŠ 정도가 적은지 νŒλ‹¨ν•˜λŠ” 데 μ‚¬μš© ) 뢄포λ₯Ό μ‚΄νŽ΄λ³΄λ‹ˆ, νƒ€μˆ˜κ°€ 50 μ΄ν•˜μΈ μ„ μˆ˜λ₯Ό μ œμ™Έν•˜λ©΄ μ μ ˆν•  것 κ°™λ‹€. 

cond = data_player['νƒ€μˆ˜'] > 50
data_player = data_player[cond].reset_index()    # 닀쀑 인덱슀 --> 컬럼으둜 λ³€κ²½ν•˜κΈ°
data_player

νƒ€μˆ˜κ°€ 50 초과인 μ„ μˆ˜λ“€λ§Œ 좔리고, μˆ˜μ›”ν•œ μ»¨νŠΈλ‘€μ„ μœ„ν•΄ reset_index()λ₯Ό μ‚¬μš©ν•˜μ—¬ 닀쀑 인덱슀λ₯Ό 컬럼으둜 λ³€κ²½ν•΄μ€€λ‹€. 

def cal_hit(df):
    '''
    - νƒ€μœ¨ : 타격에 μ„±κ³΅ν•΄μ„œ μ§„λ£¨ν•˜λŠ” λΉ„μœ¨ --> μ•ˆνƒ€ / νƒ€μˆ˜
    - 좜루율: μ‚΄μ•„μ„œ μ§„λ£¨ν•˜λŠ” λΉ„μœ¨ -->  (μ•ˆνƒ€+λ³Όλ„·+λͺΈμ—λ§žλŠ”λ³Ό)/(νƒ€μˆ˜+λ³Όλ„·+λͺΈμ—λ§žλŠ”λ³Ό+ν¬μƒν”ŒλΌμ΄)
    - μž₯νƒ€μœ¨ : νƒ€μœ¨μ— μ§„λ£¨ν•œ 베이슀 κ°€μ€‘μΉ˜ μΆ”κ°€ -->   루타 / νƒ€μˆ˜
    - OPS : 좜루율 + μž₯νƒ€μœ¨ 
    '''
    
    df['νƒ€μœ¨'] = df['μ•ˆνƒ€'] / df['νƒ€μˆ˜']
    df['좜루율'] = (df['μ•ˆνƒ€'] + df['λ³Όλ„·'] + df['사ꡬ']) / (df['νƒ€μˆ˜'] + df['λ³Όλ„·'] + df['사ꡬ'] + df['희비'])
    df['μž₯νƒ€μœ¨'] = df['루타'] / df['νƒ€μˆ˜']
    df['OPS'] = df['좜루율'] + df['μž₯νƒ€μœ¨']
    return df

λ°μ΄ν„°ν”„λ ˆμž„μ„ λ„£μ–΄ μ£Όλ©΄ best player λ₯Ό μ„ μ •ν•˜λŠ” 기쀀인 νƒ€μœ¨, 좜루율, μž₯νƒ€μœ¨, OPS μ»¬λŸΌμ„ κ³„μ‚°ν•˜μ—¬ μƒμ„±ν•˜λŠ” ν•¨μˆ˜μ΄λ‹€. 

player_stat = cal_hit(data_player)
player_stat

 

- 좜루율 -> μž₯νƒ€μœ¨ -> OPS -> νƒ€μœ¨ μˆœμ„œλŒ€λ‘œ μ •λ ¬ν•˜μ—¬ best 10 player 뽑아보기 

player_stat = player_stat.sort_values(by = ['좜루율','μž₯νƒ€μœ¨','OPS', 'νƒ€μœ¨'], ascending = False)
player_stat = player_stat.reset_index(drop = True)
player_stat.head(10)

μΈλ±μŠ€κ°€ λ’€μ£½λ°•μ£½μœΌλ‘œ μ •λ ¬λ˜λ―€λ‘œ, reset_index()λ₯Ό μ΄μš©ν•˜μ—¬ 인덱슀λ₯Ό μ •λ ¬ν•΄ μ€€λ‹€. 

 

결둠적으둜 μΆœλ£¨μœ¨μ„ κΈ°μ€€μœΌλ‘œ ν•œ KBO 2019 μ‹œμ¦Œ best playerλŠ” λ‹€μŒκ³Ό κ°™λ‹€.

player_stat['이름'][:10]

 

 

 

 


 νŒ€λ³„ μ„ μˆ˜λ“€μ˜ 좜루율 뢄포 μ‚΄νŽ΄λ³΄κΈ° 
import matplotlib
from matplotlib import font_manager, rc
import platform
import matplotlib.pyplot as plt
import seaborn as sns

# 이미지 ν•œκΈ€ ν‘œμ‹œ μ„€μ •
if platform.system() == 'Windows':  # μœˆλ„μš°μΈ 경우 맑은고딕
    font_name = font_manager.FontProperties(fname="c:/Windows/Fonts/malgun.ttf").get_name()
    rc('font', family=font_name)
else:    # Mac 인 경우 μ• ν”Œκ³ λ”•
    rc('font', family='AppleGothic')

#κ·Έλž˜ν”„μ—μ„œ λ§ˆμ΄λ„ˆμŠ€ κΈ°ν˜Έκ°€ ν‘œμ‹œλ˜λ„λ‘ ν•˜λŠ” μ„€μ •μž…λ‹ˆλ‹€.
matplotlib.rcParams['axes.unicode_minus'] = False

μš°μ„  κ·Έλž˜ν”„λ₯Ό 그렸을 λ•Œ ν•œκΈ€μ΄ κΉ¨μ§€λŠ” 것을 λ°©μ§€ν•˜κΈ° μœ„ν•΄ ν°νŠΈμ„€μ •μ„ ν•˜κ³  , λ§ˆμ΄λ„ˆμŠ€ 기호 ν‘œμ‹œ μ—¬λΆ€λ₯Ό μ„€μ •ν•œλ‹€. 

 

 

- νŒ€ 별 좜루율 뢄포 ( boxplot & swarmplot ) 

sns.boxplot(data = player_stat, x = 'νŒ€', y = '좜루율')

κ°œμˆ˜λ„ μ§κ΄€μ μœΌλ‘œ 보기 μœ„ν•΄ swarmplot을 μΆ”κ°€ ν•œλ‹€. 

sns.swarmplot(data = player_stat, x = 'νŒ€', y = '좜루율')
sns.boxplot(data = player_stat, x = 'νŒ€', y = '좜루율')

색깔이 겹치기 λ•Œλ¬Έμ— boxplot에 μ—¬λŸ¬ μ˜΅μ…˜μ„ μ£Όμ–΄ 보기 νŽΈν•˜κ²Œ λ§Œλ“€μ–΄ μ€€λ‹€. 

sns.swarmplot(data = player_stat, x = 'νŒ€', y = '좜루율')
sns.boxplot(data = player_stat, x = 'νŒ€', y = '좜루율',
            showcaps=False,             # λ°•μŠ€ 상단 κ°€λ‘œλΌμΈ 보이지 μ•ŠκΈ°
            whiskerprops={'linewidth':0}, # λ°•μŠ€ 상단 μ„Έλ‘œ 라인 보이지 μ•ŠκΈ° 
            showfliers=False,           # λ°•μŠ€ λ²”μœ„ λ²—μ–΄λ‚œ 아웃라이어 ν‘œμ‹œν•˜μ§€ μ•ŠκΈ°
            boxprops={'facecolor':'None'}, # λ°•μŠ€ 색상 μ§€μš°κΈ°
           )

μ΄λ ‡κ²Œ νŒ€λ³„ μ„ μˆ˜λ“€μ˜ 좜루율 뢄포λ₯Ό 확인해볼 수 μžˆλ‹€. NC νŒ€μ΄ κ°€μž₯ 높은 μΆœλ£¨μœ¨μ„ 가진 μ„ μˆ˜λ₯Ό λ³΄μœ ν•˜κ³  있고, 좜루율이 κ°€μž₯ 많이 λͺ°λ € μžˆλŠ” νŒ€μ€ LGνŒ€μΈ κ²ƒμœΌλ‘œ 보여지며, 좜루율의 μ€‘μœ„μˆ˜κ°€ κ°€μž₯ 높은 νŒ€μ€ 두산인 것 등을 ν•œ λˆˆμ— μ•Œ 수 μžˆλ‹€.    

 

 

 

 


 λ§ˆλ¬΄λ¦¬ : csv 파일둜 μ €μž₯ν•˜κΈ° 
file = './data/player_stat.csv'
player_stat.to_csv(file, encoding = 'cp949', index = False)

λ³Έ ν¬μŠ€νŒ…μ—μ„œ 뢄석에 μ‚¬μš©ν•œ player_stat을 csv 파일둜 μ €μž₯ν•˜λŠ” 방법이닀. 


 

 

+ Recent posts