코로나로 집에만 있는 시간이 많아져 코딩을 배워보기로 했다. 인강으로 보기만 하면 실력이 잘 늘지 않을 것 같아서 늦게 바람이 들린 판타지리그를 하는데 파이썬을 활용하면 어떨까 생각해봤다.
보통 판타지 프리미어리그 팀을 운영하면서 통계를 활용하는 경우에 쓰는 데이터는 판타지 프리미어리그 공식 API와 fbref.com의 데이터가 있다. Opta, Statsperform, Understat 등 유명한 데이터 제공 브랜드들이 많으나 아쉽게도 돈을 주고 사야 데이터를 받아볼 수 있다. fbref.com이 주요 데이터 xG, xGA등을 understat에게서 받아 무료로 풀고 있고, 또 자체 데이터도 충실해 참고할만하다. 다만, fberf.com은 API가 없어서 웹 크롤링을 통해 자료를 긁어와야 한다. 이 부분은 다음 글에서 다시 다루도록 하고, 이번 포스팅에서는 판타지 프리미어리그 공식 API에 자료를 요청하는 식에 대해 써보도록 하겠다.
판타지 프리미어리그 공식 API 요청하기
import requests
import pandas as pd
url = 'https://fantasy.premierleague.com/api/bootstrap-static/'
r = requests.get(url)
json = r.json()
json.keys()
위 여섯 줄로 판타지 프리미어리그의 공식 데이터를 컴퓨터로 불러왔다.
json.keys()로 데이터 카테고리를 프린트했다. 위 키들 중 elements, element_types, teams에 들어있는 데이터들을 사용할 예정이다. 다음으로 json 형식의 데이터를 파이썬 판다 데이터프레임으로 바꿔주는 작업을 해야한다.
새 변수에 데이터 프레임들을 저장해주고 elements 키에 들어있는 칼럼 이름들을 표시해보았다. 굉장히 많은 데이터들이 저장되어 있음을 확인할 수 있다. 이들 중 기본적인 정보들만 불러와 화면에 표시해보자.
fpl_elements_df 변수에 저장한 데이터프레임 중에서 'web_name', 'team', 'element_type', 'now_cost', 'minutes', 'total_points' 칼럼을 불러 fpl_slim_elements_df에 저장한다. 그리고 [18]에서 새 변수에 저장한 데이터를 화면에 표시해보면 team, element_type 이 숫자로만 되어있어 읽기가 어려운 면이 있다. 외질, 소크라티스, 다비드 루이즈, 오바메양 등이 team 1인 것을 보다 1이 아스날을 뜻하는 것 같다. elemen_type 은 3이 미드필더, 2가 수비수인 것 같다. 다른 키에 저장된 key: value dictionary를 숫자들을 읽을 수 있는 단어들로 바꿔보자.
element_type과 team을 새로 맵핑했다.
이제 팀에는 우리가 익히 알고 있는 아스날, 울브스가 표시가 되고, 새로 추가한 칼럼에 element_type을 맵핑한 position 이 표시가 된다. 다음 구문으로 element_type 칼럼을 지우고 칼럼 순서를 정렬해보자.
우리가 원하는 대로 잘 정렬이 되어 보여진다. 자 이제 우리가 원하는 데이터를 가져와 파이썬 데이터 형식으로 저장을 했으니 이를 통계 자료로 활용해 볼 시간이다. 현재까지 판타지 프리미어리그에서 가장 많은 포인트를 쌓은 선수가 누굴지 한 번 알아보자.
1번줄에서 total_points를 float(부동소수)형식으로 바꿔주고 total_points가 많은 순으로 표를 한 번 뽑아보았다. 케인은 현재 10.9m의 가격표를 달고 있고, 손흥민은 살라, 바디 보다 더 낮은 가격인 9.6임에도 불구하고 판타지 프리미어리그에서 두번째로 많은 포인트를 쌓았다.
지금까지
1. 판타지 프리미어리그의 공식 API를 요청해
2. 파이썬 판다 데이터프레임 형식으로 변환하고
3. 데이터를 추리고 갖춰 보기 좋게 만든 후
4. 이 데이터를 가지고 유의미한 통계를 출력해보았다.
다음은 코드 전문:
import requests
import pandas as pd
url = 'https://fantasy.premierleague.com/api/bootstrap-static/'
r = requests.get(url)
json = r.json()
json.keys()
fpl_elements_df = pd.DataFrame(json['elements'])
fpl_elements_types_df = pd.DataFrame(json['element_types'])
fpl_teams_df = pd.DataFrame(json['teams'])
fpl_elements_df.columns
fpl_slim_elements_df = fpl_elements_df[['web_name','team'
,'element_type','now_cost'
,'minutes','total_points']]
fpl_slim_elements_df['position'] = fpl_slim_elements_df.element_type.map(
fpl_elements_types_df.set_index('id').singular_name)
fpl_slim_elements_df['team'] = fpl_slim_elements_df.team.map(
fpl_teams_df.set_index('id').name)
fpl_slim_elements_df = fpl_slim_elements_df[['web_name','team'
,'position','now_cost'
,'minutes','total_points']]
fpl_slim_elements_df['total_points'] = fpl_slim_elements_df.total_points.astype(
float)
fpl_slim_elements_df.sort_values('total_points',ascending=False).head(10)
다음에는 fbref.com에서 xG, xGA 혹은 정밀한 패스 수치들을 웹 스크래핑하는 튜토리얼을 적어볼 예정이다.