반응형
Notice
Recent Posts
Recent Comments
관리 메뉴

꿈꾸는 사람.

Python::프로야구 팀순위 분석 본문

Python

Python::프로야구 팀순위 분석

현무랑 니니 2022. 7. 19. 23:50
반응형

개요

빅데이터나 데이터 사이언스가 할 일의 가장 큰 부분은 데이터 전처리이다.

데이터 전처리는 데이터 정제와 데이터 변환으로 구성된다.

 

이번 포스팅은 이전 포스팅에서 쓴 데이터를 수집을 통해 읽은 데이터를 변환하는 방법을 사례를 통해 구현해 본다.

1. 데이터 수집

이번 포스팅은 Kaggle에서 타이타닉 데이터를 다루지는 않는다.

한국 프로야구의 팀 순위 데이터를 엑셀 파일로 저장한다.

kbo.xlsx
0.01MB

순위 팀명 경기 승율 게임차 최근10경기 연속 원정
1 SSG 86 57 26 3 0.687 0 9승0무1패 6승 33-0-10 24-3-16
2 키움 87 54 32 1 0.628 4.5 6승0무4패 2패 25-1-18 29-0-14
3 LG 84 52 31 1 0.627 5 8승0무2패 1승 23-0-21 29-1-10
4 KT 84 44 38 2 0.537 12.5 9승0무1패 2승 21-1-22 23-1-16
5 KIA 83 42 40 1 0.512 14.5 4승0무6패 1패 20-0-20 22-1-20
6 롯데 85 38 44 3 0.463 18.5 5승0무5패 4승 16-3-25 22-0-19
7 두산 84 36 46 2 0.439 20.5 4승0무6패 1승 15-1-25 21-1-21
8 삼성 85 35 50 0 0.412 23 0승0무10패 11패 14-0-29 21-0-21
9 NC 83 32 49 2 0.395 24 4승0무6패 1패 17-2-22 15-0-27
10 한화 85 25 59 1 0.298 32.5 1승0무9패 6패 15-0-24 10-1-3

팀 순위 데이터를 읽어온다.

import pandas as pd

# read a dataset from the excel file
filename = 'C:/Dataset/kbo.xlsx'
sheet_name = 'kbo_2022_firsthalf'
df = pd.read_excel(filename, sheet_name=sheet_name)

2. 데이터 전처리 - 데이터 변환

2.1 Dataframe에서 특정 부분을 선택하기

먼저 읽은 데이터의 간결한 요약 정보를 알아본다..

print(df.info())


[결과]
<class 'pandas.core.frame.DataFrame'>
Int64Index: 10 entries, 0 to 9
Data columns (total 12 columns):
 #   Column  Non-Null Count  Dtype  
---  ------  --------------  -----  
 0   순위      10 non-null     int64  
 1   팀명      10 non-null     object 
 2   경기      10 non-null     int64  
 3   승       10 non-null     int64  
 4   패       10 non-null     int64  
 5   무       10 non-null     int64  
 6   승률      10 non-null     float64
 7   게임차     10 non-null     float64
 8   최근10경기  10 non-null     object 
 9   연속      10 non-null     object 
 10  홈       10 non-null     object 
 11  방문      10 non-null     object 
dtypes: float64(2), int64(5), object(5)
memory usage: 1.0+ KB
None

포스트 시즌에 진출할 팀 데이터를 보자.

team_to_play_postseason = df[df['순위'] <= 5]

print(team_to_play_postseason)
print(team_to_play_postseason.to_string(index=False))
print(team_to_play_postseason.values)

[결과]
   순위   팀명  경기   승   패  무     승률   게임차  최근10경기  연속         홈       방문
0   1  SSG  86  57  26  3  0.687   0.0  9승0무1패  6승   33-0-10  24-3-16
1   2   키움  87  54  32  1  0.628   4.5  6승0무4패  2패  25-01-18  29-0-14
2   3   LG  84  52  31  1  0.627   5.0  8승0무2패  1승   23-0-21  29-1-10
3   4   KT  84  44  38  2  0.537  12.5  9승0무1패  2승   21-1-22  23-1-16
4   5  KIA  83  42  40  1  0.512  14.5  4승0무6패  1패   20-0-20  22-1-20
=> 첫 인쇄문의 경우 순위 앞에 불필요한 인덱스가 있다.

 순위  팀명  경기  승  패  무    승률  게임차 최근10경기 연속        홈      방문
  1 SSG  86 57 26  3 0.687  0.0 9승0무1패 6승  33-0-10 24-3-16
  2  키움  87 54 32  1 0.628  4.5 6승0무4패 2패 25-01-18 29-0-14
  3  LG  84 52 31  1 0.627  5.0 8승0무2패 1승  23-0-21 29-1-10
  4  KT  84 44 38  2 0.537 12.5 9승0무1패 2승  21-1-22 23-1-16
  5 KIA  83 42 40  1 0.512 14.5 4승0무6패 1패  20-0-20 22-1-20
  => 다음 인쇄문은 데이터프레임을 테이블 형식으로 출력하는데 인덱스는 제외한다.
  
  [[1 'SSG' 86 57 26 3 0.687 0.0 '9승0무1패' '6승' '33-0-10' '24-3-16']
 [2 '키움' 87 54 32 1 0.628 4.5 '6승0무4패' '2패' '25-01-18' '29-0-14']
 [3 'LG' 84 52 31 1 0.627 5.0 '8승0무2패' '1승' '23-0-21' '29-1-10']
 [4 'KT' 84 44 38 2 0.537 12.5 '9승0무1패' '2승' '21-1-22' '23-1-16']
 [5 'KIA' 83 42 40 1 0.512 14.5 '4승0무6패' '1패' '20-0-20' '22-1-20']]
 => 마지막 인쇄문은 데이터프레임의 값만 반환한다.

홈에서 승률이 좋은 팀을 보려면 '홈' 열의 데이터를 분리해야 한다.

str.split(sep='-') 함수에서 구분 기호 '-' 를 사용하여 '승-무-패'를 '승', '무', '패'로 나눈다.

df['홈 승'] = df['홈'].str.split('-').str.get(0)
df['홈 무'] = df['홈'].str.split('-').str.get(1)
df['홈 패'] = df['홈'].str.split('-').str.get(2)
print(df.loc[:, '홈 승':'홈 패'])

[결과]
  홈 승 홈 무 홈 패
0  33   0  10
1  25   1  18
2  23   0  21
3  21   1  22
4  20   0  20
5  16   3  25
6  15   1  25
7  14   0  29
8  17   2  22
9  15   0  24

[동등한 코드]
df['홈 승'] = df['홈'].str.split('-').str[0]
df['홈 무'] = df['홈'].str.split('-').str[1]
df['홈 패'] = df['홈'].str.split('-').str[2]
print(df.loc[:, '홈 승':'홈 패'])

분리한 홈의 '승 무 패' 데이터는 문자열이므로 숫자로 변환한다.

문자열을 정수로 변환하는 함수로 pandas.to_numeric()를 사용한다.

이 함수는 실수나 정수를 반환하는데 매개변수 downcast를 사용하여 다른 dtypes을 얻을 수 있다.

변환에 오류가 있을 경우 NaN 값으로 치환하려면 'coerce'를 쓰면 된다.

 

변환을 위한 두 가지 방법을 비교해보자.

첫 번째 방법은 매개변수 downcast를 사용해 문자열을 숫자로 변환하고  가장 작은 숫자 dtype으로 다운캐스트한다.

두 번째 방법은 DataFrame.astype 함수를 사용하여 pandas 객체를 지정된 dtype으로 캐스팅한다.

# 방법1
df['홈 승'] = pd.to_numeric(df['홈 승'], downcast="integer", errors='coerce')
df['홈 무'] = pd.to_numeric(df['홈 무'], downcast="integer", errors='coerce')
df['홈 패'] = pd.to_numeric(df['홈 패'], downcast="integer", errors='coerce')
=> 변환할 때 오류가 나면 NaN로 값을 채운다.

#방법2
df['홈 승'] = pd.to_numeric(df['홈 승'], errors='coerce').fillna(0).astype(np.int64)
df['홈 무'] = pd.to_numeric(df['홈 무'], errors='coerce').fillna(0).astype(np.int64)
df['홈 패'] = pd.to_numeric(df['홈 패'], errors='coerce').fillna(0).astype(np.int64)
=> 변환할 때 오류가 나면 fillna(0)로 0으로 값을 채우고 astype(np.int64)으로 64비트 정수로 변환한다.

포스트 시즌에 진출할 수 있으면서 홈 승이 패보다 많은 팀의 데이터를 구해보자

포스트 시즌은 상위 5개 팀이 진출하므로 'df['순위'] <= 5' 조건을 적용하고

홈 승이 패보다 많은 조건은 'df['홈 승'] > df['홈 패']'를 사용한다.

그리고 인덱스 없이 인쇄하기 위해 DataFrame.to_string() 함수에 매개변수 index를 False로 설정한다.

top5_and_homewinner = df[(df['순위'] <= 5) & (df['홈 승'] > df['홈 패'])]
print(top5_and_homewinner.to_string(index=False))

[결과]
 순위  팀명  경기  승  패  무    승률  게임차 최근10경기 연속       홈      방문  홈 승  홈 무  홈 패
  1 SSG  86 57 26  3 0.687  0.0 9승0무1패 6승 33-0-10 24-3-16   33    0   10
  2  키움  87 54 32  1 0.628  4.5 6승0무4패 2패 25-1-18 29-0-14   25    1   18
  3  LG  84 52 31  1 0.627  5.0 8승0무2패 1승 23-0-21 29-1-10   23    0   21

데이터 변환에 사용한 기능을 요약하면 데이터 타입 변환, 문자열 분리 및 조건문 적용 등이다.

 

반응형
Comments