본문 바로가기
AI/AI 부트캠프

[AI 부트캠프] DAY 32 - EDA 프로젝트 3

by HOHHOH 2023. 8. 31.

[오늘의 일지]

EDA 프로젝트 - 수집 자료 세부적으로 수정하기

[상세 내용]

EDA 프로젝트

선수 이름 통합하기

- 어제 힘들게 하드코딩을 해서 선수 이름의 알파벳을 동일하게 만들어 주었습니다. 그리고 그 자료를 이용해서 다른 자료들과 비교해 보니 충분히 일치되는 부분들이 늘어났지만 아직도 일치되지 못하고 버려지는 자료들이 거의 30프로 이상이나 되었던 거 같습니다. 그래서 어려가지 방법을 생각해서 각각의 자료의 선수들의 이름을 통합시킬 방법을 생각해 보았습니다. 

 

시행착오

- 처음에는 여러 가지로 많은 생각을 했습니다. 성과 이름사이에 빈칸이 차이가 있는 것은 아닐까 이름과 성에 존재하는 대소문자의 구별 때문이 아닐까 등의 생각을 거쳐서 몇 가지 실험적인 측면에서 임시로 작업을 해봤습니다. 작업의 내용은 다음과 같습니다.

  • 오타 찾아보기
  • 각 선수들의 이름에 대소문자를 통합시키기
  • 이름 사이에 '-'이 끼어 있는 선수들 제거시키기
  • 성과 이름이 반대로 되어 있나 확인해 보기(한국 선수들이 이 경우에 많이 그랬습니다.)
  • 선수 이름을 별명으로 지칭하는 선수들 찾아보기(많은 경우에서 이렇게 사용하고 있었습니다.)

처음으로 오타를 가친 선수를 찾아보았는데 한두 명 정도의 오타만 발생했던 것으로 파악이 되어서 큰 영향이 없을 거라고 생각했습니다. 두 번째로 선수들의 이름을 대소문자 중 하나로 통합은 과정과 이름 사이에 '-'를 제거하는 과정을 거쳤을 때 두 경우를 합쳐서 5명 정도밖에 없던 걸로 확인했습니다. 물론 EPL이라는 리그에 한국선수들이 많이 존재하는 것도 아니었기 때문에 결과적으로 별명을 이름으로 사용하는 선수들 때문에 많은 오차가 발생했을 거라고 판단을 내렸습니다. 일단 전 과정의 진행을 코드로 보겠습니다.

# 빈칸 없애주기
for index, row in defensive.iterrows():
    name_strip = row["Name"].replace(' ','')
    defensive.at[index, "Name"] = name_strip
    
# '-' 없애주기
for index, row in defensive.iterrows():
    name_strip = row["Name"].replace('-','')
    defensive.at[index, "Name"] = name_strip
    
# 소문자로 만들어주기
for index, row in defensive.iterrows():
    name_strip = row["Name"].lower()
    defensive.at[index, "Name"] = name_strip

 

결국 별명을 가진 선수들을 outer join을 해서 리스트를 만들어 준 뒤 정렬해서 찾기

- 결국 선수들을 하나하나 찾아서 딕셔너리로 정리해서 이름을 변경시켜 줬습니다. 시간은 오래 걸렸지만 가장 확실한 방법이었기 때문에 작업이 모두 끝났을 때는 오차율이 많이 떨어진 걸로 확인했습니다.

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',
    'Alisson': 'Alisson Becker',
    'Amad Diallo Traore': 'Amad Diallo',
    'Andrew Robertson': 'Andy Robertson',
    'Andriy Yarmolenko': 'Andrii Yarmolenko',
    'Armel Bella Kotchap': 'Armel Bella-Kotchap',
    'Arnaut Danjuma Groeneveld': 'Arnaut Danjuma',
    'Benoit Badiashile Mukinayi': 'Benoit Badiashile',
    'Bernardo': 'Bernardo Espinosa',
    'Bobby Reid': 'Bobby De Cordova-Reid',
    'Brad Jones': 'Bradley Jones',
    'Bryan Gil Salvatierra': 'Bryan Gil',
    'Cheick Oumar Doucoure': 'Cheick Doucoure',
    'Daniel Bentley': 'Dan Bentley',
    'Daniel Drinkwater': 'Danny Drinkwater',
    "Daniel N'Lundulu": 'Daniel Nlundulu',
    'Emile Smith-Rowe': 'Emile Smith Rowe',
    'Eric Maxim Choupo-Moting': 'Eric Choupo-Moting',
    'Estupinan': 'Pervis Estupinan',
    'Ezri Konsa Ngoyo': 'Ezri Konsa',
    'Facao': 'Radamel Falcao',
    'Faustino Anjorin': 'Tino Anjorin',
    'Fernando Marcal': 'Marcal',
    'Franck Zambo': 'Andre-Frank Zambo Anguissa',
    'Hamed Junior Traore': 'Hamed Traore',
    'Hee-Chan Hwang': 'Hwang Hee-Chan',
    'Ian Poveda-Ocampo': 'Ian Poveda',
    'Jaden Philogene-Bidace': 'Jaden Philogene',
    'Joe Ayodele-Aribo': 'Joe Aribo',
    "Joey O'Brien": "Joseph O'Brien",
    'Johann Berg Gudmundsson': 'Johann Gudmundsson',
    'Jonathan Williams': 'Jonny Williams',
    'Jonny': 'Jonny Otto',
    'Jose Angel Crespo': 'Jose Crespo',
    'Jose Pozo': 'Jose Angel Pozo',
    'Jose Reina': 'Pepe Reina',
    'Joseph Gomez': 'Joe Gomez',
    'Joseph Hodge': 'Joe Hodge',
    'Joseph Whitworth': 'Joe Whitworth',
    'Joshua Sargent': 'Josh Sargent',
    'Juan Camilo Hernandez': 'Cucho Hernandez',
    'Juan Zuniga': 'Juan Camilo Zuniga',
    'Jurado': 'Jose Manuel Jurado',
    'Ki Sung-yueng': 'Ki Sung-Yueng',
    'Konstantinos Tsimikas': 'Kostas Tsimikas',
    'Lasse Sorenson': 'Lasse Soerensen',
    'Lee Chung-yong': 'Lee Chung-Yong',
    'Leo Fuhr Hjelde': 'Leo Hjelde',
    'Mads Bech Soerensen': 'Mads Bech',
    'Mame Biram Diouf': 'Mame Diouf',
    'Martin Odegaard': 'Martin Oedegaard',
    'Mat Ryan': 'Mathew Ryan',
    'Matt Worthington': 'Matthew Worthington',
    'Matthew Cash': 'Matty Cash',
    'Matthew James': 'Matty James',
    'Matthew Longstaff': 'Matty Longstaff',
    'Max Gradel': 'Max-Alain Gradel',
    'Max Kilman': 'Maximilian Kilman',
    'Naif Aguerd': 'Nayef Aguerd',
    "Nicolas N'Koulou": 'Nicolas Nkoulou',
    'Nsue': 'Emilio Nsue',
    'Nyom': 'Allan-Romeo Nyom',
    'Oghenekaro Etebo': 'Peter Etebo',
    'Pape Sarr': 'Pape Matar Sarr',
    'Papiss Demba Cisse': 'Papiss Cisse',
    'Rayan Ait Nouri': 'Rayan Ait-Nouri',
    'Ritchie de Laet': 'Ritchie De Laet',
    'Robbie Brady': 'Robert Brady',
    'Santiago Cazorla': 'Santi Cazorla',
    'Sokratis': 'Sokratis Papastathopoulos',
    "Steven N'Zonzi": 'Steven Nzonzi',
    'Tanguy NDombele Alvaro': 'Tanguy Ndombele',
    'Toti': 'Toti Gomes',
    'Tyias Browning': 'Jiang Guangtai',
    'Valentino Livramento': 'Tino Livramento',
    'Vicente Iborra': 'Iborra',
    'William Smallbone': 'Will Smallbone'
}
# input and output 파일 경로
input_file_path = "C:/Users/LEGION/Downloads/EDA 프로젝트/understat_all.csv"
output_file_path = "C:/Users/LEGION/Downloads/EDA 프로젝트/understat_all0.csv"

convert_csv_values(input_file_path, output_file_path, "Player", detail_list)

 

- 추가로 발견한 선수들

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 = {
    'David De Gea': 'David de Gea',
    'Virgil Van Dijk': 'Virgil van Dijk',
    'Rodrigo Hernandez Cascante': 'Rodri',
    'Daniel Bentley': 'Dan Bentley',
    'Carlos Casimiro': 'Casemiro',
    'Kepa Arrizabalaga': 'Kepa',
    'Fabinho Tavares': 'Fabinho',
    'Antony dos Santo': 'Antony',
    'Frederico de Paula Santos': 'Fred',
    'Jorge Luiz Frello Filho': 'Jorginho',
    'Edward Nketiah': 'Eddie Nketiah',
    'David Fofana': 'David Datro Fofana',
    'Rodrigo Machado': 'Rodrigo',
    'Andrew Robertson': 'Andy Robertson',
    'Ederson Moraes': 'Ederson',
    'Jose Moutinho': 'Joao Moutinho',
    'Emerson Palmieri': 'Emerson',
    'Richarlison de Andrade': 'Richarlison',
    'Joelinton Cassio Apolinario de Lira': 'Joelinton',
    'Felipe Augusto de Almeida': 'Felipe',
    'Onyinye Ndidi': 'Wilfred Ndidi',
    'Pape Sarr': 'Pape Matar Sarr',
    'Pierre-Emile Hojbjerg': 'Pierre-Emile Hoejbjerg',
    'Heung-Min Son': 'Son Heung-Min',
    'Alex Oxlade-Chamberlain': 'Alex Oxlade Chamberlain',
    'Jared Bowen': 'Jarrod Bowen',
    'Vitaliy Mykolenko': 'Vitalii Mykolenko'
                }
# input and output 파일 경로
input_file_path = "C:/Users/LEGION/Downloads/EDA 프로젝트/salary_all.csv"
output_file_path = "C:/Users/LEGION/Downloads/EDA 프로젝트/salary_all0.csv"

convert_csv_values(input_file_path, output_file_path, "Name", detail_list)

 

마지막으로 이름이 중복인 선수들

- 이름이 중복인 선수들은 그냥 대체로 변경시키면 데이터에 큰 오류가 발생할 것입니다. 그래서 그냥 데이터를 버릴 생각이었지만 다행히도 중복인 선수들이 'No'라는 고유의 칼럼의 각자 다른 번호를 가지고 있어고 번호 별로 팀과 년도를 찾아서 이름을 매칭해서 변경시켜 줬습니다. 중복선수 이름이 곤란한 이유로 예시를 하나 들자면 아스널이라는 팀에 가브리엘이라는 선수가 지금까지 4명이었습니다. Gabriel Paulista, Gabriel Magalhães, Gabriel Martinelli, Gabriel Jesus 이 중에서 두 명이 그냥 Gabriel을 사용하고 있었던 것입니다. 그래서 고유 넘버를 가지고 있었던 것이 다행이었던 점입니다. 해결은 다음과 같이 했습니다.

import pandas as pd

def no_convert(num,nam):
    # CSV파일 읽기
    csv_path = 'C:/Users/LEGION/Downloads/understat_all.csv'
    df = pd.read_csv(csv_path)

    for i in range(0,len(df[df['No'] == num])):
        # 'No'칼럼에서 원하는 번호 찾기
        row_index = df[df['No'] == num].index[i]

        # 새로운 값으로 바꿔주기
        new_name = nam
        df.at[row_index, 'Player'] = new_name

    # CSV 파일 수정해서 위에 덮어쓰기
    df.to_csv(csv_path, index=False, encoding='utf-8-sig')

    print(df[df['No'] == num])

no_list = {493:'Gabriel Paulista',5613:'Gabriel Magalhaes',7430:'Emerson Royal',}

for key, value in no_list.items():
    no_convert(key,value)

 

[마무리]

 오늘은 join을 하기 위한 가장 중요한 지표인 이름을 공통적인 형태로 통합하는 과정을 세부적인 수정을 통해서 거의 마무리했습니다. 이제 join을 하기 위한 전처리는 어느 정도 마무리가 되었기 때문에 내일이면 데이터를 서로 비교 가능할 수도 있을 거 같습니다. 이번에 데이터들을 수정하면서 느꼈던 거지만 역시 공식적으로 주어지는 자료들이 아니기 때문에 이러한 과정들이 꼭 필요하다는 생각도 들었고 현업에서는 자주 겪게 될 일일 것이라고 긍정적으로 생각하면서 재미있게 작업을 수행했습니다. 

반응형

댓글