[오늘의 일지]
EDA 프로젝트 - 자료 수집 마무리, 데이터 분석 시작
[상세 내용]
EDA 프로젝트
자료 수집 수정 마무리
- 어제 작업을 마무리한 줄 알았지만 오늘 새롭게 크롤링해 왔던 연봉정보에 대한 자료가 조금 선수들 이름에서 차이가 있어서 마지막으로 정보를 수정했습니다. 수정을 마치고 다른 자료들과 오차율을 구해봤는데 3프로 때의 매우 적은 수치를 보였습니다. 다행이라고 생각합니다.
import pandas as pd
def convert_csv_values(input_file, output_file, column_name, value_mapping):
# Load the CSV file
df = pd.read_csv(input_file)
# 칼럼에 딕셔너리 key를 value로 변경하는 과정
df[column_name] = df[column_name].replace(value_mapping)
# 새로운 CSV file로 저장
df.to_csv(output_file, index=False, encoding='utf-8-sig')
detail_list = {'Ahmed Elmohamady': 'Ahmed El Mohamady',
'Alex Oxlade-Chamberlain': 'Alex Oxlade Chamberlain',
'Alex Song': 'Alexandre Song',
'Robbie Brady': 'Robert Brady',
'Cheik Tiote': 'Cheick Tiote',
'Andrew Robertson': 'Andy Robertson',
"Joey O'Brien": "Joseph O'Brien",
'Rob Green': 'Robert Green',
'Papiss Demba Cisse': 'Papiss Cisse',
'Falcao': 'Radamel Falcao',
'Matthew Upson': 'Matt Upson',
'Jonathan Williams': 'Jonny Williams',
'John Mikel Obi': 'John Obi Mikel',
'Rob Elliot': 'Robert Elliot',
'Will Buckley': 'William Buckley',
'Brad Jones': 'Bradley Jones',
'Tyias Browning': 'Jiang Guangtai',
'Danny Lafferty': 'Daniel Lafferty',
'Jose Pozo': 'Jose Angel Pozo',
'Izzy Brown': 'Isaiah Brown',
'Zeki Fryers': 'Ezekiel Fryers',
'Alexander Sorloth': 'Alexander Soerloth',
'Alisson': 'Alisson Becker',
'Allan Nyom': 'Allan-Romeo Nyom',
'Andre Zambo Anguissa': 'Andre-Frank Zambo Anguissa',
'Bobby Reid': 'Bobby De Cordova-Reid',
'Kell Watts': 'Kelland Watts',
'Charly Musonda Jr': 'Charly Musonda',
'Christian Norgaard': 'Christian Noergaard',
'Daniel Bentley': 'Dan Bentley',
'Dan Agyei': 'Daniel Agyei',
"Dan N'Lundulu": 'Daniel Nlundulu',
'Dimitrios Giannoulis': 'Dimitris Giannoulis',
'Eric Maxim Choupo-Moting': 'Eric Choupo-Moting',
'Fin Stevens': 'Finley Stevens',
"Georges-Kevin N'Koudou": "Georges-Kevin Nkoudou",
'Hamed Junior Traore': 'Hamed Traore',
'Vicente Iborra': 'Iborra',
'Ilya Zabarnyi': 'Illia Zabarnyi',
'Jacob Lungi Sorensen': 'Jacob Soerensen',
'Joao Carlos Teixeira': 'Joao Teixeira',
'Johann Berg Gudmundsson': 'Johann Gudmundsson',
'Jon Gorenc-Stankovic': 'Jon Gorenc Stankovic',
'Jonathan Howson': 'Jonny Howson',
'Joe Dodoo': 'Joseph Dodoo',
'Jota Peleteiro': 'Jota',
'Camilo Zuniga': 'Juan Camilo Zuniga',
'Kepa Arrizabalaga': 'Kepa',
'Konstantinos Tsimikas': 'Kostas Tsimikas',
'Lasse Sorensen': 'Lasse Soerensen',
'Leo Fuhr Hjelde': 'Leo Hjelde',
'Mads Bech Sorensen': 'Mads Bech',
'Mads Roerslev Rasmussen': 'Mads Roerslev',
'Martin Odegaard': 'Martin Oedegaard',
'Matt Worthington': 'Matthew Worthington',
'Matthew Longstaff': 'Matty Longstaff',
'Max Gradel': 'Max-Alain Gradel',
'Max Kilman': 'Maximilian Kilman',
"Nicolas N'Koulou": 'Nicolas Nkoulou',
'Orjan Nyland': 'Oerjan Nyland',
'Pape Sarr': 'Pape Matar Sarr',
'Oghenekaro Etebo': 'Peter Etebo',
'Pierre-Emile Hojbjerg': 'Pierre-Emile Hoejbjerg',
'Stefan Ortega Moreno': 'Stefan Ortega',
'Khanya Leshabela': 'Thakgalo Leshabela',
'Thiago': 'Thiago Alcantara',
'Tom Edwards': 'Thomas Edwards',
'Tommy Robson': 'Thomas Robson',
'Vitaliy Mykolenko': 'Vitalii Mykolenko',
'Bojan Krkic':'Bojan'}
# input and output 파일 경로
input_file_path = "C:/Users/LEGION/Downloads/capology_all.csv"
output_file_path = "C:/Users/LEGION/Downloads/capology_all0.csv"
convert_csv_values(input_file_path, output_file_path, "Name", detail_list)
본격적으로 데이터 분석을 위한 자료 통합
- 이제 데이터 분석을 하기 위해서 자료들을 통합해야 하는 상황이 있었습니다. 다행히 저희 조에서 백엔드 개발자 출신 분이 한 명 있었는데 코딩을 잘하셔서 정말 든든했습니다. 다 같이 분석할 자료를 통합 매뉴얼을 정리해서 공유해 주셨습니다. 그렇게 자료가 완성이 되었고 이제 세부적으로 어떻게 분석할 것인가에 대해서 생각하면 될 거 같습니다. 공유해 주신 자료를 통합하는 과정은 아래와 같습니다. 중간에 null값이 존재하는 것은 과감하게 버려줬습니다. 그렇게 최종적을 분석할 수 있는 값의 수가 4588개의 행이 되었습니다.
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
# plyaer data load 및 정리(프로필)
player_df = pd.read_csv('./players_all.csv')
player_df = player_df.rename(columns={'Unnamed: 0':'Id'}).drop(['No.', 'Id'], axis=1)
# 1xbet data load 및 정리(스탯)
xbet_df = pd.read_csv('./1xbet_all.csv')
xbet_df = xbet_df.drop(['Team','Age','Position'], axis=1).rename(columns={'Drb_x':'Drb_Off', 'Drb_y':'Drb_Def'})
# understat data load 및 정리(스탯)
understat_df = pd.read_csv('./understat_all0.csv')
understat_df = understat_df.drop(['No','Team'], axis=1)
# capology load(연봉)
capology_df = pd.read_csv('./capology_all0.csv')
# 프로필 + 연봉
eda_df = player_df.merge(capology_df[['Weekly Salary','Base Salary','ADJ Salary','Name', 'year']], how='left', left_on=['Name', 'year'], right_on=['Name', 'year'])
eda_df = eda_df[~eda_df.duplicated(['year', 'Name'], keep='first')] # 중복 제거
# 프로필 + 연봉 + 스탯(understat)
eda_df = eda_df.merge(understat_df, how='left', left_on=['Name', 'year'], right_on=['Name', 'year'])
# 프로필 + 연봉 + 스탯(understat) + 스탯(1xbet)
eda_df = eda_df.merge(
xbet_df[[
'Name', 'year', 'SpG', 'KeyP', 'Drb_Off', 'Fouled', 'Off',
'Disp', 'UnsTch', 'Rating', 'Tackles', 'Inter','Fouls',
'Offsides', 'Clear', 'Drb_Def', 'Blocks', 'AvgP', 'PS%']],
how='left',
left_on=['Name', 'year'],
right_on=['Name', 'year']
)
eda_df = eda_df.dropna()
eda_df.info()
>>>
<class 'pandas.core.frame.DataFrame'>
Int64Index: 4588 entries, 0 to 4754
Data columns (total 43 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 year 4588 non-null int64
1 Name 4588 non-null object
2 Age 4588 non-null int64
3 Team 4588 non-null object
4 Position 4588 non-null object
5 Weekly Salary 4588 non-null float64
6 Base Salary 4588 non-null float64
7 ADJ Salary 4588 non-null float64
8 Apps 4588 non-null float64
9 Min 4588 non-null float64
10 G 4588 non-null float64
11 NPG 4588 non-null float64
12 A 4588 non-null float64
13 xG 4588 non-null float64
14 NPxG 4588 non-null float64
15 xA 4588 non-null float64
16 xGChain 4588 non-null float64
17 xGBuildup 4588 non-null float64
18 xG90 4588 non-null float64
19 NPxG90 4588 non-null float64
20 xA90 4588 non-null float64
21 xG90+xA90 4588 non-null float64
22 NPxG90+xA90 4588 non-null float64
23 xGChain90 4588 non-null float64
24 xGBuildup90 4588 non-null float64
25 SpG 4588 non-null float64
26 KeyP 4588 non-null float64
27 Drb_Off 4588 non-null float64
28 Fouled 4588 non-null float64
29 Off 4588 non-null float64
30 Disp 4588 non-null float64
31 UnsTch 4588 non-null float64
32 Rating 4588 non-null float64
33 Tackles 4588 non-null float64
34 Inter 4588 non-null float64
35 Fouls 4588 non-null float64
36 Offsides 4588 non-null float64
37 Clear 4588 non-null float64
38 Drb_Def 4588 non-null float64
39 Blocks 4588 non-null float64
40 AvgP 4588 non-null float64
41 PS% 4588 non-null float64
42 Age Lev 4588 non-null object
dtypes: float64(37), int64(2), object(4)
memory usage: 1.5+ MB
간단하게 지표들 확인해 보기
- 우선적으로 나이에 대한 확률 밀도 그래프를 볼 수 있는 kdeplot을 해보고 분포가 잘 되어 있는지 확인해 봤는데 정규분포 형태의 그래프가 잘 나온 거 같습니다.
sns.kdeplot(data=eda_df, x='Age')
- 그렇다면 나이와 출전 횟수 간의 확률 밀도 그래프는 어떨지 나타내 보겠습니다. 확실히 어린선수들은 출전 횟수가 적은 곳에서 밀집되어 있고 25세~30세쯤 되는 선수들이 거의 많은 경기를 소화한다고 밀집되어 있는 걸로 봐서는 일반적으로 그 나이 때가 전성기에 가까운 나이 때라고 생각했습니다.
sns.kdeplot(data=eda_df, x='Age' , y='Apps' )
- 마지막으로 나이와 연봉 간의 확률 밀도 그래프를 만들어 보고 생각해 봤습니다. 확실히 전성기 때라고 생각한 25~30세 사이에 연봉의 고점이 높게 형성되어 있다는 걸 알게 되었고 생각보다 전성기 나이 때에서도 상대적으로 저연봉 선수들이 훨씬 많이 밀집되어 있어 편차가 심하다는 것도 알게 되었습니다.
sns.kdeplot(data=eda_df, x='Age' , y='ADJ Salary' )
plt.axis([12,40,0,15000000])
[마무리]
오늘은 수집한 모든 자료의 수정을 마치고 앞으로 분석자료로서 모두 하나로 통합하는 것까지 매뉴얼을 완성해서 간단한 그래프를 그려보는 것까지 했습니다. 특히 확률 밀도 그래프를 통해서 특정 칼럼이 어디 구간에 나이별로 밀집이 되어있지를 확인해서 대략저인 전성기 나이 때를 알아볼 수 있었습니다. 내일부터는 처음 저희 조가 분석 목표로 잡았던 연봉과 선수의 성적 간의 관계에 대해서 세부적으로 설정하여 분석하는 과정을 해야 될 거 같습니다.
'AI > AI 부트캠프' 카테고리의 다른 글
[AI 부트캠프] DAY 35 - EDA 프로젝트 6 (0) | 2023.09.05 |
---|---|
[AI 부트캠프] DAY 34 - EDA 프로젝트 5 (0) | 2023.09.02 |
[AI 부트캠프] DAY 32 - EDA 프로젝트 3 (0) | 2023.08.31 |
[AI 부트캠프] DAY 31 - EDA 프로젝트 2 (0) | 2023.08.30 |
[AI 부트캠프] DAY 30 - EDA 프로젝트 1 (0) | 2023.08.29 |
댓글