{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
" "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Data Parsing of Wyscout Event Data\n",
"##### Notebook to parse JSON data from [Wyscout](https://wyscout.com/) to create one unified Events DataFrame.\n",
"\n",
"### By [Edd Webster](https://www.twitter.com/eddwebster)\n",
"Notebook first written: 26/01/2021 \n",
"Notebook last updated: 12/02/2021\n",
"\n",
"![title](../../img/logos/wyscout_logo.png)\n",
"\n",
"Click [here](#section5) to jump straight to the Exploratory Data Analysis section and skip the [Task Brief](#section2), [Data Sources](#section3), and [Data Engineering](#section4) sections. Or click [here](#section6) to jump straight to the Conclusion."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"---\n",
"\n",
"## Introduction \n",
"This notebook parses pubicly available [Wyscout](https://wyscout.com/) Event data for the 'Big 5' European leagues for the 17/18 mens season, the 2016 European Championship, and the 2018 FIFA Mens World Cup, using [pandas](http://pandas.pydata.org/) for data manipulation through DataFrames.\n",
"\n",
"For more information about this notebook and the author, I'm available through all the following channels:\n",
"* [eddwebster.com](https://www.eddwebster.com/);\n",
"* edd.j.webster@gmail.com;\n",
"* [@eddwebster](https://www.twitter.com/eddwebster);\n",
"* [linkedin.com/in/eddwebster](https://www.linkedin.com/in/eddwebster/);\n",
"* [github/eddwebster](https://github.com/eddwebster/);\n",
"* [public.tableau.com/profile/edd.webster](https://public.tableau.com/profile/edd.webster);\n",
"* [kaggle.com/eddwebster](https://www.kaggle.com/eddwebster); and\n",
"* [hackerrank.com/eddwebster](https://www.hackerrank.com/eddwebster).\n",
"\n",
"![title](../../img/edd_webster/fifa21eddwebsterbanner.png)\n",
"\n",
"The accompanying GitHub repository for this notebook can be found [here](https://github.com/eddwebster/football_analytics) and a static version of this notebook can be found [here](https://nbviewer.jupyter.org/github/eddwebster/football_analytics/blob/master/notebooks/2_data_parsing/Wyscout%20Parsing.ipynb)."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"___\n",
"\n",
"## Notebook Contents \n",
"1. [Notebook Dependencies](#section1) \n",
"2. [Project Brief](#section2) \n",
"3. [Data Sources](#section3) \n",
" 1. [Introduction](#section3.1) \n",
" 2. [Download the Data](#section3.2) \n",
" 3. [Read in the Datasets](#section3.3) \n",
" 4. [Join the Datasets](#section3.4) \n",
" 5. [Initial Data Handling](#section3.5) \n",
"4. [Data Engineering](#section4) \n",
" 1. [Sort the DataFrame](#section4.1) \n",
"5. [Export DataFrame](#section5) \n",
"6. [Summary](#section6) \n",
"7. [Next Steps](#section7) \n",
"8. [Bibliography](#section8) "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"---\n",
"\n",
"## 1. Notebook Dependencies "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"This notebook was written using [Python 3](https://docs.python.org/3.7/) and requires the following libraries:\n",
"* [`Jupyter notebooks`](https://jupyter.org/) for this notebook environment with which this project is presented;\n",
"* [`NumPy`](http://www.numpy.org/) for multidimensional array computing;\n",
"* [`pandas`](http://pandas.pydata.org/) for data analysis and manipulation; and\n",
"* `tqdm` for a clean progress bar;\n",
"\n",
"All packages used for this notebook except for BeautifulSoup can be obtained by downloading and installing the [Conda](https://anaconda.org/anaconda/conda) distribution, available on all platforms (Windows, Linux and Mac OSX). Step-by-step guides on how to install Anaconda can be found for Windows [here](https://medium.com/@GalarnykMichael/install-python-on-windows-anaconda-c63c7c3d1444) and Mac [here](https://medium.com/@GalarnykMichael/install-python-on-mac-anaconda-ccd9f2014072), as well as in the Anaconda documentation itself [here](https://docs.anaconda.com/anaconda/install/)."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Import Libraries and Modules"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Setup Complete\n"
]
}
],
"source": [
"%load_ext autoreload\n",
"%autoreload 2\n",
"\n",
"# Python ≥3.5 (ideally)\n",
"import platform\n",
"import sys, getopt\n",
"assert sys.version_info >= (3, 5)\n",
"import csv\n",
"\n",
"# Import Dependencies\n",
"%matplotlib inline\n",
"\n",
"# Math Operations\n",
"import numpy as np\n",
"import math\n",
"from math import pi\n",
"\n",
"# Datetime\n",
"import datetime\n",
"from datetime import date\n",
"import time\n",
"\n",
"# Data Preprocessing\n",
"import pandas as pd\n",
"import os\n",
"import re\n",
"import random\n",
"from io import BytesIO\n",
"from pathlib import Path\n",
"\n",
"# Reading directories\n",
"import glob\n",
"import os\n",
"from os.path import basename\n",
"\n",
"# Working with JSON\n",
"import json\n",
"from pandas.io.json import json_normalize\n",
"\n",
"# Data Visualisation\n",
"import matplotlib as mpl\n",
"import matplotlib.pyplot as plt\n",
"from matplotlib import patches\n",
"from matplotlib.patches import Arc\n",
"import seaborn as sns\n",
"plt.style.use('seaborn-whitegrid')\n",
"import missingno as msno\n",
"\n",
"# Downloading data sources\n",
"from urllib.parse import urlparse\n",
"from urllib.request import urlopen, urlretrieve\n",
"from zipfile import ZipFile, is_zipfile\n",
"from tqdm import tqdm # Progress Bar\n",
"\n",
"# Display in Jupyter\n",
"from IPython.display import Image, Video, YouTubeVideo\n",
"from IPython.core.display import HTML\n",
"\n",
"# Ignore Warnings\n",
"import warnings\n",
"warnings.filterwarnings(action=\"ignore\", message=\"^internal gelsd\")\n",
"\n",
"print('Setup Complete')"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Python: 3.7.6\n",
"NumPy: 1.18.0\n",
"pandas: 1.2.0\n",
"matplotlib: 3.3.2\n",
"Seaborn: 0.11.1\n"
]
}
],
"source": [
"# Python / module versions used here for reference\n",
"print('Python: {}'.format(platform.python_version()))\n",
"print('NumPy: {}'.format(np.__version__))\n",
"print('pandas: {}'.format(pd.__version__))\n",
"print('matplotlib: {}'.format(mpl.__version__))\n",
"print('Seaborn: {}'.format(sns.__version__))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Defined Variables"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [],
"source": [
"# Define today's date\n",
"today = datetime.datetime.now().strftime('%d/%m/%Y').replace('/', '')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Defined Filepaths"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [],
"source": [
"# Set up initial paths to subfolders\n",
"base_dir = os.path.join('..', '..',)\n",
"data_dir = os.path.join(base_dir, 'data')\n",
"data_dir_wyscout = os.path.join(base_dir, 'data', 'wyscout')\n",
"scripts_dir = os.path.join(base_dir, 'scripts')\n",
"scripts_dir_wyscout = os.path.join(base_dir, 'scripts', 'wyscout')\n",
"img_dir = os.path.join(base_dir, 'img')\n",
"fig_dir = os.path.join(base_dir, 'img', 'fig')\n",
"fig_dir_wyscout = os.path.join(base_dir, 'img', 'fig', 'wyscout')\n",
"video_dir = os.path.join(base_dir, 'video')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Create Directory Structure"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [],
"source": [
"# make the directory structure\n",
"for folder in ['competitions', 'combined', 'events', 'matches', 'players', 'teams']:\n",
" path = os.path.join(data_dir_wyscout, 'raw', folder)\n",
" if not os.path.exists(path):\n",
" os.mkdir(path)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Custom Functions"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [],
"source": [
"# Define custom function to read JSON files that also handles the encoding of special characters e.g. accents in names of players and teams\n",
"def read_json_file(filename):\n",
" with open(filename, 'rb') as json_file:\n",
" return BytesIO(json_file.read()).getvalue().decode('unicode_escape')\n",
" \n",
"# Define custom function to flatten pandas DataFrames with nested JSON columns. Source: https://stackoverflow.com/questions/39899005/how-to-flatten-a-pandas-dataframe-with-some-columns-as-json\n",
"def flatten_nested_json_df(df):\n",
"\n",
" df = df.reset_index()\n",
"\n",
" print(f\"original shape: {df.shape}\")\n",
" print(f\"original columns: {df.columns}\")\n",
"\n",
"\n",
" # search for columns to explode/flatten\n",
" s = (df.applymap(type) == list).all()\n",
" list_columns = s[s].index.tolist()\n",
"\n",
" s = (df.applymap(type) == dict).all()\n",
" dict_columns = s[s].index.tolist()\n",
"\n",
" print(f\"lists: {list_columns}, dicts: {dict_columns}\")\n",
" while len(list_columns) > 0 or len(dict_columns) > 0:\n",
" new_columns = []\n",
"\n",
" for col in dict_columns:\n",
" print(f\"flattening: {col}\")\n",
" # explode dictionaries horizontally, adding new columns\n",
" horiz_exploded = pd.json_normalize(df[col]).add_prefix(f'{col}.')\n",
" horiz_exploded.index = df.index\n",
" df = pd.concat([df, horiz_exploded], axis=1).drop(columns=[col])\n",
" new_columns.extend(horiz_exploded.columns) # inplace\n",
"\n",
" for col in list_columns:\n",
" print(f\"exploding: {col}\")\n",
" # explode lists vertically, adding new columns\n",
" df = df.drop(columns=[col]).join(df[col].explode().to_frame())\n",
" new_columns.append(col)\n",
"\n",
" # check if there are still dict o list fields to flatten\n",
" s = (df[new_columns].applymap(type) == list).all()\n",
" list_columns = s[s].index.tolist()\n",
"\n",
" s = (df[new_columns].applymap(type) == dict).all()\n",
" dict_columns = s[s].index.tolist()\n",
"\n",
" print(f\"lists: {list_columns}, dicts: {dict_columns}\")\n",
"\n",
" print(f\"final shape: {df.shape}\")\n",
" print(f\"final columns: {df.columns}\")\n",
" return df"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Notebook Settings"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [],
"source": [
"# Display all DataFrame columns\n",
"pd.set_option('display.max_columns', None)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"---\n",
"\n",
"## 2. Project Brief \n",
"This Jupyter notebook explores how to parse pubicly available [Wyscout](https://wyscout.com/) JSON data of football matches for the Big 5 European leagues for the 17/18 season using [pandas](http://pandas.pydata.org/) for data manipulation through DataFrames.\n",
"\n",
"The resulting five engineered DataFrames for each of the Big 5 European league are exported to CSV files. This data can be further analysed in Python, joined to other datasets, or explored using Tableau, PowerBI, Microsoft Excel.\n",
"\n",
"**Notebook Conventions**: \n",
"* Variables that refer a `DataFrame` object are prefixed with `df_`.\n",
"* Variables that refer to a collection of `DataFrame` objects (e.g., a list, a set or a dict) are prefixed with `dfs_`.\n",
"\n",
"**References**: \n",
"This notebook uses Wyscout data, made publicly available in the following paper by Luca Pappalardo, Paolo Cintia, Alessio Rossi, Emanuele Massucco, Paolo Ferragina, Dino Pedreschi, and Fosca Giannotti. **[A Public Data Set of Spatio-Temporal Match Events in Soccer Competitions](https://www.nature.com/articles/s41597-019-0247-7)**. In *Scientific Data 6*, no. 1 (2019): 1-15."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"---\n",
"\n",
"## 3. Data Sources "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 3.1. Introduction "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### 3.1.1. About Wyscout \n",
"[Wyscout](https://wyscout.com/) is an Italian company that supports football scouting, match analysis and transfer dynamics. The company was founded in Genoa, Italy in 2004 and provides video analysis tools and digital databases regarding performances and matches for coaches, teams and players dealing with football business.\n",
"\n",
"![title](../../img/wyscout_logo.png)\n",
"\n",
"The purpose is to allow them have a detailed sight of a large number of athletes about individual performances, patterns of play and tactical strategy.\n",
"\n",
"This notebook explores a complete dataset of event data for the Big 5 European leagues during the 17/18 season."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### 3.1.2. About the Wyscout publicly available data \n",
"A detailed description of the data can be found in the following paper:\n",
"- Pappalardo, L., Cintia, P., Rossi, A. et al. **A public data set of spatio-temporal match events in soccer competitions**. Scientific Data 6, 236 (2019) doi:10.1038/s41597-019-0247-7, https://www.nature.com/articles/s41597-019-0247-7\n",
"\n",
"It is from this paper import the *matches*, *events*, *players*, *playerank*, *referees*, *coaches*, and *competition* data sets from the figshare repository . Data are stored in the `JSON` format. \n",
"\n",
"The complete data set contains:\n",
"- 1,941 matches\n",
"- 3,251,294 events\n",
"- 4,299 players.\n",
"\n",
"The datasets we will be using are:\n",
"- competitions;\n",
"- events;\n",
"- matches;\n",
"- players; and\n",
"- teams\n",
"\n",
"The data needs to be imported as a DataFrame in the Data Sources section [Section 3](#section3) and cleaned in the Data Engineering section [Section 4](#section4)."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 3.2. Download the Data \n",
"This section downloads the Wyscout datasets if not already present in the data folder.\n",
"\n",
"The following `data_files` dictionary lists the four data files in the Wyscout dataset:\n",
"* `events` (73.74 MB): match events for the matches in the dataset;\n",
"* `matches` (629.98 kB): overview of the matches in the dataset;\n",
"* `players` (1.66 MB): information on the players in the dataset;\n",
"* `teams` (26.76 kB): information on the teams in the dataset."
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [],
"source": [
"# Define dict in Python where the keys are the names of the files and the values are the corresponding URLs\n",
"data_files = {'events': 'https://ndownloader.figshare.com/files/14464685', # ZIP file containing one JSON file for each competition\n",
" 'matches': 'https://ndownloader.figshare.com/files/14464622', # ZIP file containing one JSON file for each competition\n",
" 'players': 'https://ndownloader.figshare.com/files/15073721', # JSON file\n",
" 'teams': 'https://ndownloader.figshare.com/files/15073697' # JSON file\n",
" }"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The following cell loops through the `data_files` dictionary, downloads each listed data file if it is not already present in the directory, and stores each downloaded data file to the local file system.\n",
"\n",
"If the downloaded data file is a ZIP archive, the included JSON files are extracted from the ZIP archive and stored to the local file system."
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [],
"source": [
"# Download the listed data files for events, matches, players, and teams\n",
"if not os.path.exists(data_dir_wyscout + '/raw/json/'):\n",
" for url in tqdm(data_files.values()):\n",
" url_s3 = urlopen(url).geturl()\n",
" path = Path(urlparse(url_s3).path)\n",
" file_name = path.name\n",
" file_local, _ = urlretrieve(url_s3, file_name)\n",
" if is_zipfile(file_local):\n",
" with ZipFile(file_local) as zip_file:\n",
" zip_file.extractall()\n",
"else:\n",
" pass "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 3.3. Read in Data \n",
"The following cells read the the `JSON` files into a `DataFrame` object with some basic Data Engineering to flatten the data and select only the columns of interest."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### 3.3.1. Teams "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"##### Data dictionary\n",
"The [Wyscout](https://wyscout.com/) Events dataset has twelve features (columns) with the following definitions and data types:\n",
"\n",
"| Feature | Data type |\n",
"|------|-----|\n",
"| `eventId` | int64 |\n",
"| `subEventName` | object |\n",
"| `tags` | object |\n",
"| `playerId` | int64 |\n",
"| `positions` | object |\n",
"| `matchId` | int64 |\n",
"| `eventName` | object |\n",
"| `teamId` | int64 |\n",
"| `matchPeriod` | object |\n",
"| `eventSec` | float64 |\n",
"| `subEventId` | object |\n",
"| `id` | int64 |\n",
"\n",
"Refer to the Wyscout [API docs](https://apidocs.wyscout.com/) and [Events Manual](https://footballdata.wyscout.com/wp-content/uploads/2018/03/Wyscout-Events-Manual.pdf) for further information about event and subevents."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"##### Read in JSON file"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"
\n",
"\n",
"
\n",
" \n",
" \n",
" \n",
" city \n",
" name \n",
" wyId \n",
" officialName \n",
" area \n",
" type \n",
" \n",
" \n",
" \n",
" \n",
" 0 \n",
" Newcastle upon Tyne \n",
" Newcastle United \n",
" 1613 \n",
" Newcastle United FC \n",
" {'name': 'England', 'id': '0', 'alpha3code': '... \n",
" club \n",
" \n",
" \n",
" 1 \n",
" Vigo \n",
" Celta de Vigo \n",
" 692 \n",
" Real Club Celta de Vigo \n",
" {'name': 'Spain', 'id': '724', 'alpha3code': '... \n",
" club \n",
" \n",
" \n",
" 2 \n",
" Barcelona \n",
" Espanyol \n",
" 691 \n",
" Reial Club Deportiu Espanyol \n",
" {'name': 'Spain', 'id': '724', 'alpha3code': '... \n",
" club \n",
" \n",
" \n",
" 3 \n",
" Vitoria-Gasteiz \n",
" Deportivo Alavés \n",
" 696 \n",
" Deportivo Alavés \n",
" {'name': 'Spain', 'id': '724', 'alpha3code': '... \n",
" club \n",
" \n",
" \n",
" 4 \n",
" Valencia \n",
" Levante \n",
" 695 \n",
" Levante UD \n",
" {'name': 'Spain', 'id': '724', 'alpha3code': '... \n",
" club \n",
" \n",
" \n",
"
\n",
"
"
],
"text/plain": [
" city name wyId officialName \\\n",
"0 Newcastle upon Tyne Newcastle United 1613 Newcastle United FC \n",
"1 Vigo Celta de Vigo 692 Real Club Celta de Vigo \n",
"2 Barcelona Espanyol 691 Reial Club Deportiu Espanyol \n",
"3 Vitoria-Gasteiz Deportivo Alavés 696 Deportivo Alavés \n",
"4 Valencia Levante 695 Levante UD \n",
"\n",
" area type \n",
"0 {'name': 'England', 'id': '0', 'alpha3code': '... club \n",
"1 {'name': 'Spain', 'id': '724', 'alpha3code': '... club \n",
"2 {'name': 'Spain', 'id': '724', 'alpha3code': '... club \n",
"3 {'name': 'Spain', 'id': '724', 'alpha3code': '... club \n",
"4 {'name': 'Spain', 'id': '724', 'alpha3code': '... club "
]
},
"execution_count": 9,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# Read JSON file as a JSON string and create a pandas DataFrame form the resulting JSON string\n",
"json_teams = read_json_file(data_dir_wyscout + '/raw/json/' + 'teams.json')\n",
"df_teams = pd.read_json(json_teams)\n",
"\n",
"# Display DataFrame\n",
"df_teams.head()"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(142, 6)"
]
},
"execution_count": 10,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df_teams.shape"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"##### Normalise nested columns"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {
"scrolled": true
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"original shape: (142, 7)\n",
"original columns: Index(['index', 'city', 'name', 'wyId', 'officialName', 'area', 'type'], dtype='object')\n",
"lists: [], dicts: ['area']\n",
"flattening: area\n",
"lists: [], dicts: []\n",
"final shape: (142, 10)\n",
"final columns: Index(['index', 'city', 'name', 'wyId', 'officialName', 'type', 'area.name',\n",
" 'area.id', 'area.alpha3code', 'area.alpha2code'],\n",
" dtype='object')\n"
]
},
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" \n",
" index \n",
" city \n",
" name \n",
" wyId \n",
" officialName \n",
" type \n",
" area.name \n",
" area.id \n",
" area.alpha3code \n",
" area.alpha2code \n",
" \n",
" \n",
" \n",
" \n",
" 0 \n",
" 0 \n",
" Newcastle upon Tyne \n",
" Newcastle United \n",
" 1613 \n",
" Newcastle United FC \n",
" club \n",
" England \n",
" 0 \n",
" XEN \n",
" \n",
" \n",
" \n",
" 1 \n",
" 1 \n",
" Vigo \n",
" Celta de Vigo \n",
" 692 \n",
" Real Club Celta de Vigo \n",
" club \n",
" Spain \n",
" 724 \n",
" ESP \n",
" ES \n",
" \n",
" \n",
" 2 \n",
" 2 \n",
" Barcelona \n",
" Espanyol \n",
" 691 \n",
" Reial Club Deportiu Espanyol \n",
" club \n",
" Spain \n",
" 724 \n",
" ESP \n",
" ES \n",
" \n",
" \n",
" 3 \n",
" 3 \n",
" Vitoria-Gasteiz \n",
" Deportivo Alavés \n",
" 696 \n",
" Deportivo Alavés \n",
" club \n",
" Spain \n",
" 724 \n",
" ESP \n",
" ES \n",
" \n",
" \n",
" 4 \n",
" 4 \n",
" Valencia \n",
" Levante \n",
" 695 \n",
" Levante UD \n",
" club \n",
" Spain \n",
" 724 \n",
" ESP \n",
" ES \n",
" \n",
" \n",
"
\n",
"
"
],
"text/plain": [
" index city name wyId \\\n",
"0 0 Newcastle upon Tyne Newcastle United 1613 \n",
"1 1 Vigo Celta de Vigo 692 \n",
"2 2 Barcelona Espanyol 691 \n",
"3 3 Vitoria-Gasteiz Deportivo Alavés 696 \n",
"4 4 Valencia Levante 695 \n",
"\n",
" officialName type area.name area.id area.alpha3code \\\n",
"0 Newcastle United FC club England 0 XEN \n",
"1 Real Club Celta de Vigo club Spain 724 ESP \n",
"2 Reial Club Deportiu Espanyol club Spain 724 ESP \n",
"3 Deportivo Alavés club Spain 724 ESP \n",
"4 Levante UD club Spain 724 ESP \n",
"\n",
" area.alpha2code \n",
"0 \n",
"1 ES \n",
"2 ES \n",
"3 ES \n",
"4 ES "
]
},
"execution_count": 11,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# Flatten the nested dictionaries\n",
"df_teams_flat = flatten_nested_json_df(df_teams)\n",
"\n",
"# Display DataFrame\n",
"df_teams_flat.head()"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(142, 10)"
]
},
"execution_count": 12,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df_teams_flat.shape"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"##### Rename columns"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"/opt/anaconda3/lib/python3.7/site-packages/ipykernel_launcher.py:2: FutureWarning: The default value of regex will change from True to False in a future version.\n",
" \n"
]
}
],
"source": [
"# Rename column\n",
"df_teams_flat.columns = df_teams_flat.columns.str.replace('[.]', '_')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"##### Streamline the DataFrame"
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"Index(['index', 'city', 'name', 'wyId', 'officialName', 'type', 'area_name',\n",
" 'area_id', 'area_alpha3code', 'area_alpha2code'],\n",
" dtype='object')"
]
},
"execution_count": 14,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# Display DataFrame columns\n",
"df_teams_flat.columns"
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {},
"outputs": [],
"source": [
"# Select columns of interest\n",
"cols_teams = ['name', 'wyId']\n",
"\n",
"# Create more concise DataFrame using only columns of interest\n",
"df_teams_flat_select = df_teams_flat[cols_teams]"
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(142, 2)"
]
},
"execution_count": 16,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df_teams_flat_select.shape"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"##### Export DataFrames"
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {},
"outputs": [],
"source": [
"# Export DataFrame as a CSV file\n",
"if not os.path.exists(os.path.join(data_dir_wyscout, 'raw', 'csv', 'teams.csv')):\n",
" df_teams_flat.to_csv(os.path.join(data_dir_wyscout, 'raw', 'csv', 'teams.csv'), index=None, header=True)\n",
"else:\n",
" pass"
]
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {},
"outputs": [],
"source": [
"# Export DataFrame as a CSV file\n",
"if not os.path.exists(os.path.join(data_dir_wyscout, 'raw', 'csv', 'teams_select.csv')):\n",
" df_teams_flat_select.to_csv(os.path.join(data_dir_wyscout, 'raw', 'csv', 'teams_select.csv'), index=None, header=True)\n",
"else:\n",
" pass"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### 3.3.2. Players "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"##### Data Dictionary\n",
"The [Wyscout](https://wyscout.com/) Events dataset has twelve features (columns) with the following definitions and data types:\n",
"\n",
"| Feature | Data type |\n",
"|------|-----|\n",
"| `eventId` | int64 |\n",
"| `subEventName` | object |\n",
"| `tags` | object |\n",
"| `playerId` | int64 |\n",
"| `positions` | object |\n",
"| `matchId` | int64 |\n",
"| `eventName` | object |\n",
"| `teamId` | int64 |\n",
"| `matchPeriod` | object |\n",
"| `eventSec` | float64 |\n",
"| `subEventId` | object |\n",
"| `id` | int64 |\n",
"\n",
"Refer to the Wyscout [API docs](https://apidocs.wyscout.com/) and [Events Manual](https://footballdata.wyscout.com/wp-content/uploads/2018/03/Wyscout-Events-Manual.pdf) for further information about event and subevents."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"##### Read JSON file"
]
},
{
"cell_type": "code",
"execution_count": 19,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" \n",
" passportArea \n",
" weight \n",
" firstName \n",
" middleName \n",
" lastName \n",
" currentTeamId \n",
" birthDate \n",
" height \n",
" role \n",
" birthArea \n",
" wyId \n",
" foot \n",
" shortName \n",
" currentNationalTeamId \n",
" \n",
" \n",
" \n",
" \n",
" 0 \n",
" {'name': 'Turkey', 'id': '792', 'alpha3code': ... \n",
" 78 \n",
" Harun \n",
" \n",
" Tekin \n",
" 4502 \n",
" 1989-06-17 \n",
" 187 \n",
" {'code2': 'GK', 'code3': 'GKP', 'name': 'Goalk... \n",
" {'name': 'Turkey', 'id': '792', 'alpha3code': ... \n",
" 32777 \n",
" right \n",
" H. Tekin \n",
" 4687 \n",
" \n",
" \n",
" 1 \n",
" {'name': 'Senegal', 'id': '686', 'alpha3code':... \n",
" 73 \n",
" Malang \n",
" \n",
" Sarr \n",
" 3775 \n",
" 1999-01-23 \n",
" 182 \n",
" {'code2': 'DF', 'code3': 'DEF', 'name': 'Defen... \n",
" {'name': 'France', 'id': '250', 'alpha3code': ... \n",
" 393228 \n",
" left \n",
" M. Sarr \n",
" 4423 \n",
" \n",
" \n",
" 2 \n",
" {'name': 'France', 'id': '250', 'alpha3code': ... \n",
" 72 \n",
" Over \n",
" \n",
" Mandanda \n",
" 3772 \n",
" 1998-10-26 \n",
" 176 \n",
" {'code2': 'GK', 'code3': 'GKP', 'name': 'Goalk... \n",
" {'name': 'France', 'id': '250', 'alpha3code': ... \n",
" 393230 \n",
" \n",
" O. Mandanda \n",
" null \n",
" \n",
" \n",
" 3 \n",
" {'name': 'Senegal', 'id': '686', 'alpha3code':... \n",
" 82 \n",
" Alfred John Momar \n",
" \n",
" N'Diaye \n",
" 683 \n",
" 1990-03-06 \n",
" 187 \n",
" {'code2': 'MD', 'code3': 'MID', 'name': 'Midfi... \n",
" {'name': 'France', 'id': '250', 'alpha3code': ... \n",
" 32793 \n",
" right \n",
" A. N'Diaye \n",
" 19314 \n",
" \n",
" \n",
" 4 \n",
" {'name': 'France', 'id': '250', 'alpha3code': ... \n",
" 84 \n",
" Ibrahima \n",
" \n",
" Konaté \n",
" 2975 \n",
" 1999-05-25 \n",
" 192 \n",
" {'code2': 'DF', 'code3': 'DEF', 'name': 'Defen... \n",
" {'name': 'France', 'id': '250', 'alpha3code': ... \n",
" 393247 \n",
" right \n",
" I. Konaté \n",
" null \n",
" \n",
" \n",
"
\n",
"
"
],
"text/plain": [
" passportArea weight \\\n",
"0 {'name': 'Turkey', 'id': '792', 'alpha3code': ... 78 \n",
"1 {'name': 'Senegal', 'id': '686', 'alpha3code':... 73 \n",
"2 {'name': 'France', 'id': '250', 'alpha3code': ... 72 \n",
"3 {'name': 'Senegal', 'id': '686', 'alpha3code':... 82 \n",
"4 {'name': 'France', 'id': '250', 'alpha3code': ... 84 \n",
"\n",
" firstName middleName lastName currentTeamId birthDate height \\\n",
"0 Harun Tekin 4502 1989-06-17 187 \n",
"1 Malang Sarr 3775 1999-01-23 182 \n",
"2 Over Mandanda 3772 1998-10-26 176 \n",
"3 Alfred John Momar N'Diaye 683 1990-03-06 187 \n",
"4 Ibrahima Konaté 2975 1999-05-25 192 \n",
"\n",
" role \\\n",
"0 {'code2': 'GK', 'code3': 'GKP', 'name': 'Goalk... \n",
"1 {'code2': 'DF', 'code3': 'DEF', 'name': 'Defen... \n",
"2 {'code2': 'GK', 'code3': 'GKP', 'name': 'Goalk... \n",
"3 {'code2': 'MD', 'code3': 'MID', 'name': 'Midfi... \n",
"4 {'code2': 'DF', 'code3': 'DEF', 'name': 'Defen... \n",
"\n",
" birthArea wyId foot \\\n",
"0 {'name': 'Turkey', 'id': '792', 'alpha3code': ... 32777 right \n",
"1 {'name': 'France', 'id': '250', 'alpha3code': ... 393228 left \n",
"2 {'name': 'France', 'id': '250', 'alpha3code': ... 393230 \n",
"3 {'name': 'France', 'id': '250', 'alpha3code': ... 32793 right \n",
"4 {'name': 'France', 'id': '250', 'alpha3code': ... 393247 right \n",
"\n",
" shortName currentNationalTeamId \n",
"0 H. Tekin 4687 \n",
"1 M. Sarr 4423 \n",
"2 O. Mandanda null \n",
"3 A. N'Diaye 19314 \n",
"4 I. Konaté null "
]
},
"execution_count": 19,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# Read JSON file as a JSON string and create a pandas DataFrame form the resulting JSON string\n",
"json_players = read_json_file(data_dir_wyscout + '/raw/json/' + 'players.json')\n",
"df_players = pd.read_json(json_players)\n",
"\n",
"# Display DataFrame\n",
"df_players.head()"
]
},
{
"cell_type": "code",
"execution_count": 20,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(3603, 14)"
]
},
"execution_count": 20,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df_players.shape"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"##### Normalise nested columns"
]
},
{
"cell_type": "code",
"execution_count": 21,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"original shape: (3603, 15)\n",
"original columns: Index(['index', 'passportArea', 'weight', 'firstName', 'middleName',\n",
" 'lastName', 'currentTeamId', 'birthDate', 'height', 'role', 'birthArea',\n",
" 'wyId', 'foot', 'shortName', 'currentNationalTeamId'],\n",
" dtype='object')\n",
"lists: [], dicts: ['passportArea', 'role', 'birthArea']\n",
"flattening: passportArea\n",
"flattening: role\n",
"flattening: birthArea\n",
"lists: [], dicts: []\n",
"final shape: (3603, 23)\n",
"final columns: Index(['index', 'weight', 'firstName', 'middleName', 'lastName',\n",
" 'currentTeamId', 'birthDate', 'height', 'wyId', 'foot', 'shortName',\n",
" 'currentNationalTeamId', 'passportArea.name', 'passportArea.id',\n",
" 'passportArea.alpha3code', 'passportArea.alpha2code', 'role.code2',\n",
" 'role.code3', 'role.name', 'birthArea.name', 'birthArea.id',\n",
" 'birthArea.alpha3code', 'birthArea.alpha2code'],\n",
" dtype='object')\n"
]
},
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" \n",
" index \n",
" weight \n",
" firstName \n",
" middleName \n",
" lastName \n",
" currentTeamId \n",
" birthDate \n",
" height \n",
" wyId \n",
" foot \n",
" shortName \n",
" currentNationalTeamId \n",
" passportArea.name \n",
" passportArea.id \n",
" passportArea.alpha3code \n",
" passportArea.alpha2code \n",
" role.code2 \n",
" role.code3 \n",
" role.name \n",
" birthArea.name \n",
" birthArea.id \n",
" birthArea.alpha3code \n",
" birthArea.alpha2code \n",
" \n",
" \n",
" \n",
" \n",
" 0 \n",
" 0 \n",
" 78 \n",
" Harun \n",
" \n",
" Tekin \n",
" 4502 \n",
" 1989-06-17 \n",
" 187 \n",
" 32777 \n",
" right \n",
" H. Tekin \n",
" 4687 \n",
" Turkey \n",
" 792 \n",
" TUR \n",
" TR \n",
" GK \n",
" GKP \n",
" Goalkeeper \n",
" Turkey \n",
" 792 \n",
" TUR \n",
" TR \n",
" \n",
" \n",
" 1 \n",
" 1 \n",
" 73 \n",
" Malang \n",
" \n",
" Sarr \n",
" 3775 \n",
" 1999-01-23 \n",
" 182 \n",
" 393228 \n",
" left \n",
" M. Sarr \n",
" 4423 \n",
" Senegal \n",
" 686 \n",
" SEN \n",
" SN \n",
" DF \n",
" DEF \n",
" Defender \n",
" France \n",
" 250 \n",
" FRA \n",
" FR \n",
" \n",
" \n",
" 2 \n",
" 2 \n",
" 72 \n",
" Over \n",
" \n",
" Mandanda \n",
" 3772 \n",
" 1998-10-26 \n",
" 176 \n",
" 393230 \n",
" \n",
" O. Mandanda \n",
" null \n",
" France \n",
" 250 \n",
" FRA \n",
" FR \n",
" GK \n",
" GKP \n",
" Goalkeeper \n",
" France \n",
" 250 \n",
" FRA \n",
" FR \n",
" \n",
" \n",
" 3 \n",
" 3 \n",
" 82 \n",
" Alfred John Momar \n",
" \n",
" N'Diaye \n",
" 683 \n",
" 1990-03-06 \n",
" 187 \n",
" 32793 \n",
" right \n",
" A. N'Diaye \n",
" 19314 \n",
" Senegal \n",
" 686 \n",
" SEN \n",
" SN \n",
" MD \n",
" MID \n",
" Midfielder \n",
" France \n",
" 250 \n",
" FRA \n",
" FR \n",
" \n",
" \n",
" 4 \n",
" 4 \n",
" 84 \n",
" Ibrahima \n",
" \n",
" Konaté \n",
" 2975 \n",
" 1999-05-25 \n",
" 192 \n",
" 393247 \n",
" right \n",
" I. Konaté \n",
" null \n",
" France \n",
" 250 \n",
" FRA \n",
" FR \n",
" DF \n",
" DEF \n",
" Defender \n",
" France \n",
" 250 \n",
" FRA \n",
" FR \n",
" \n",
" \n",
"
\n",
"
"
],
"text/plain": [
" index weight firstName middleName lastName currentTeamId \\\n",
"0 0 78 Harun Tekin 4502 \n",
"1 1 73 Malang Sarr 3775 \n",
"2 2 72 Over Mandanda 3772 \n",
"3 3 82 Alfred John Momar N'Diaye 683 \n",
"4 4 84 Ibrahima Konaté 2975 \n",
"\n",
" birthDate height wyId foot shortName currentNationalTeamId \\\n",
"0 1989-06-17 187 32777 right H. Tekin 4687 \n",
"1 1999-01-23 182 393228 left M. Sarr 4423 \n",
"2 1998-10-26 176 393230 O. Mandanda null \n",
"3 1990-03-06 187 32793 right A. N'Diaye 19314 \n",
"4 1999-05-25 192 393247 right I. Konaté null \n",
"\n",
" passportArea.name passportArea.id passportArea.alpha3code \\\n",
"0 Turkey 792 TUR \n",
"1 Senegal 686 SEN \n",
"2 France 250 FRA \n",
"3 Senegal 686 SEN \n",
"4 France 250 FRA \n",
"\n",
" passportArea.alpha2code role.code2 role.code3 role.name birthArea.name \\\n",
"0 TR GK GKP Goalkeeper Turkey \n",
"1 SN DF DEF Defender France \n",
"2 FR GK GKP Goalkeeper France \n",
"3 SN MD MID Midfielder France \n",
"4 FR DF DEF Defender France \n",
"\n",
" birthArea.id birthArea.alpha3code birthArea.alpha2code \n",
"0 792 TUR TR \n",
"1 250 FRA FR \n",
"2 250 FRA FR \n",
"3 250 FRA FR \n",
"4 250 FRA FR "
]
},
"execution_count": 21,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# Flatten the nested dictionaries\n",
"df_players_flat = flatten_nested_json_df(df_players)\n",
"\n",
"# Display DataFrame\n",
"df_players_flat.head()"
]
},
{
"cell_type": "code",
"execution_count": 22,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(3603, 23)"
]
},
"execution_count": 22,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df_players_flat.shape"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"##### Rename columns"
]
},
{
"cell_type": "code",
"execution_count": 23,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"/opt/anaconda3/lib/python3.7/site-packages/ipykernel_launcher.py:2: FutureWarning: The default value of regex will change from True to False in a future version.\n",
" \n"
]
}
],
"source": [
"# Rename columns\n",
"df_players_flat.columns = df_players_flat.columns.str.replace('[.]', '_')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"##### Streamline the DataFrame"
]
},
{
"cell_type": "code",
"execution_count": 24,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"Index(['index', 'weight', 'firstName', 'middleName', 'lastName',\n",
" 'currentTeamId', 'birthDate', 'height', 'wyId', 'foot', 'shortName',\n",
" 'currentNationalTeamId', 'passportArea_name', 'passportArea_id',\n",
" 'passportArea_alpha3code', 'passportArea_alpha2code', 'role_code2',\n",
" 'role_code3', 'role_name', 'birthArea_name', 'birthArea_id',\n",
" 'birthArea_alpha3code', 'birthArea_alpha2code'],\n",
" dtype='object')"
]
},
"execution_count": 24,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# Display DataFrame columns\n",
"df_players_flat.columns"
]
},
{
"cell_type": "code",
"execution_count": 25,
"metadata": {},
"outputs": [],
"source": [
"# Select columns of interest\n",
"cols_players = ['weight',\n",
" 'firstName',----\n",
" 'middleName',\n",
" 'lastName',\n",
" 'birthDate',\n",
" 'height',\n",
" 'wyId',\n",
" 'foot',\n",
" 'shortName',\n",
" 'passportArea_name',\n",
" 'role_name',\n",
" 'birthArea_name'\n",
" ]\n",
"\n",
"# Create more concise DataFrame using only columns of interest\n",
"df_players_flat_select = df_players_flat[cols_players]"
]
},
{
"cell_type": "code",
"execution_count": 26,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(3603, 12)"
]
},
"execution_count": 26,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df_players_flat_select.shape"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"##### Export DataFrame"
]
},
{
"cell_type": "code",
"execution_count": 27,
"metadata": {},
"outputs": [],
"source": [
"# Export DataFrame as a CSV file\n",
"if not os.path.exists(os.path.join(data_dir_wyscout, 'raw', 'csv', 'players.csv')):\n",
" df_players_flat.to_csv(os.path.join(data_dir_wyscout, 'raw', 'csv', 'players.csv'), index=None, header=True)\n",
"else:\n",
" pass"
]
},
{
"cell_type": "code",
"execution_count": 28,
"metadata": {},
"outputs": [],
"source": [
"# Export DataFrame as a CSV file\n",
"if not os.path.exists(os.path.join(data_dir_wyscout, 'raw', 'csv', 'players_select.csv')):\n",
" df_players_flat_select.to_csv(os.path.join(data_dir_wyscout, 'raw', 'csv', 'players_select.csv'), index=None, header=True)\n",
"else:\n",
" pass"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### 3.3.3. Matches "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"##### Data Dictionary\n",
"The [Wyscout](https://wyscout.com/) Events dataset has twelve features (columns) with the following definitions and data types:\n",
"\n",
"| Feature | Data type |\n",
"|------|-----|\n",
"| `eventId` | int64 |\n",
"| `subEventName` | object |\n",
"| `tags` | object |\n",
"| `playerId` | int64 |\n",
"| `positions` | object |\n",
"| `matchId` | int64 |\n",
"| `eventName` | object |\n",
"| `teamId` | int64 |\n",
"| `matchPeriod` | object |\n",
"| `eventSec` | float64 |\n",
"| `subEventId` | object |\n",
"| `id` | int64 |\n",
"\n",
"Refer to the Wyscout [API docs](https://apidocs.wyscout.com/) and [Events Manual](https://footballdata.wyscout.com/wp-content/uploads/2018/03/Wyscout-Events-Manual.pdf) for further information about event and subevents."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"##### Define competitions\n",
"The following cell lists the competitions to be included in the dataset. Dataset includes data for seven different competitions - 5 domestic and 2 international."
]
},
{
"cell_type": "code",
"execution_count": 29,
"metadata": {},
"outputs": [],
"source": [
"# Define a list to select only the competitions of interest. \n",
"# For this Expected Goals model, I will use all the data available\n",
"\n",
"# Define list of competitions\n",
"competitions = ['England',\n",
" 'France',\n",
" 'Germany',\n",
" 'Italy',\n",
" 'Spain',\n",
" 'European Championship',\n",
" 'World Cup'\n",
" ]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"##### Read JSON files\n",
"The following cells read the `matches.json` files for the selected competitions into a `DataFrame` object."
]
},
{
"cell_type": "code",
"execution_count": 30,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" \n",
" status \n",
" roundId \n",
" gameweek \n",
" teamsData \n",
" seasonId \n",
" dateutc \n",
" winner \n",
" venue \n",
" wyId \n",
" label \n",
" date \n",
" referees \n",
" duration \n",
" competitionId \n",
" groupName \n",
" \n",
" \n",
" \n",
" \n",
" 0 \n",
" Played \n",
" 4405654 \n",
" 38 \n",
" {'1646': {'scoreET': 0, 'coachId': 8880, 'side... \n",
" 181150 \n",
" 2018-05-13 14:00:00 \n",
" 1659 \n",
" Turf Moor \n",
" 2500089 \n",
" Burnley - AFC Bournemouth, 1 - 2 \n",
" May 13, 2018 at 4:00:00 PM GMT+2 \n",
" [{'refereeId': 385705, 'role': 'referee'}, {'r... \n",
" Regular \n",
" 364 \n",
" NaN \n",
" \n",
" \n",
" 1 \n",
" Played \n",
" 4405654 \n",
" 38 \n",
" {'1628': {'scoreET': 0, 'coachId': 8357, 'side... \n",
" 181150 \n",
" 2018-05-13 14:00:00 \n",
" 1628 \n",
" Selhurst Park \n",
" 2500090 \n",
" Crystal Palace - West Bromwich Albion, 2 - 0 \n",
" May 13, 2018 at 4:00:00 PM GMT+2 \n",
" [{'refereeId': 381851, 'role': 'referee'}, {'r... \n",
" Regular \n",
" 364 \n",
" NaN \n",
" \n",
" \n",
" 2 \n",
" Played \n",
" 4405654 \n",
" 38 \n",
" {'1609': {'scoreET': 0, 'coachId': 7845, 'side... \n",
" 181150 \n",
" 2018-05-13 14:00:00 \n",
" 1609 \n",
" The John Smith's Stadium \n",
" 2500091 \n",
" Huddersfield Town - Arsenal, 0 - 1 \n",
" May 13, 2018 at 4:00:00 PM GMT+2 \n",
" [{'refereeId': 384965, 'role': 'referee'}, {'r... \n",
" Regular \n",
" 364 \n",
" NaN \n",
" \n",
" \n",
" 3 \n",
" Played \n",
" 4405654 \n",
" 38 \n",
" {'1651': {'scoreET': 0, 'coachId': 8093, 'side... \n",
" 181150 \n",
" 2018-05-13 14:00:00 \n",
" 1612 \n",
" Anfield \n",
" 2500092 \n",
" Liverpool - Brighton & Hove Albion, 4 - 0 \n",
" May 13, 2018 at 4:00:00 PM GMT+2 \n",
" [{'refereeId': 385704, 'role': 'referee'}, {'r... \n",
" Regular \n",
" 364 \n",
" NaN \n",
" \n",
" \n",
" 4 \n",
" Played \n",
" 4405654 \n",
" 38 \n",
" {'1644': {'scoreET': 0, 'coachId': 93112, 'sid... \n",
" 181150 \n",
" 2018-05-13 14:00:00 \n",
" 1611 \n",
" Old Trafford \n",
" 2500093 \n",
" Manchester United - Watford, 1 - 0 \n",
" May 13, 2018 at 4:00:00 PM GMT+2 \n",
" [{'refereeId': 381853, 'role': 'referee'}, {'r... \n",
" Regular \n",
" 364 \n",
" NaN \n",
" \n",
" \n",
"
\n",
"
"
],
"text/plain": [
" status roundId gameweek \\\n",
"0 Played 4405654 38 \n",
"1 Played 4405654 38 \n",
"2 Played 4405654 38 \n",
"3 Played 4405654 38 \n",
"4 Played 4405654 38 \n",
"\n",
" teamsData seasonId \\\n",
"0 {'1646': {'scoreET': 0, 'coachId': 8880, 'side... 181150 \n",
"1 {'1628': {'scoreET': 0, 'coachId': 8357, 'side... 181150 \n",
"2 {'1609': {'scoreET': 0, 'coachId': 7845, 'side... 181150 \n",
"3 {'1651': {'scoreET': 0, 'coachId': 8093, 'side... 181150 \n",
"4 {'1644': {'scoreET': 0, 'coachId': 93112, 'sid... 181150 \n",
"\n",
" dateutc winner venue wyId \\\n",
"0 2018-05-13 14:00:00 1659 Turf Moor 2500089 \n",
"1 2018-05-13 14:00:00 1628 Selhurst Park 2500090 \n",
"2 2018-05-13 14:00:00 1609 The John Smith's Stadium 2500091 \n",
"3 2018-05-13 14:00:00 1612 Anfield 2500092 \n",
"4 2018-05-13 14:00:00 1611 Old Trafford 2500093 \n",
"\n",
" label \\\n",
"0 Burnley - AFC Bournemouth, 1 - 2 \n",
"1 Crystal Palace - West Bromwich Albion, 2 - 0 \n",
"2 Huddersfield Town - Arsenal, 0 - 1 \n",
"3 Liverpool - Brighton & Hove Albion, 4 - 0 \n",
"4 Manchester United - Watford, 1 - 0 \n",
"\n",
" date \\\n",
"0 May 13, 2018 at 4:00:00 PM GMT+2 \n",
"1 May 13, 2018 at 4:00:00 PM GMT+2 \n",
"2 May 13, 2018 at 4:00:00 PM GMT+2 \n",
"3 May 13, 2018 at 4:00:00 PM GMT+2 \n",
"4 May 13, 2018 at 4:00:00 PM GMT+2 \n",
"\n",
" referees duration competitionId \\\n",
"0 [{'refereeId': 385705, 'role': 'referee'}, {'r... Regular 364 \n",
"1 [{'refereeId': 381851, 'role': 'referee'}, {'r... Regular 364 \n",
"2 [{'refereeId': 384965, 'role': 'referee'}, {'r... Regular 364 \n",
"3 [{'refereeId': 385704, 'role': 'referee'}, {'r... Regular 364 \n",
"4 [{'refereeId': 381853, 'role': 'referee'}, {'r... Regular 364 \n",
"\n",
" groupName \n",
"0 NaN \n",
"1 NaN \n",
"2 NaN \n",
"3 NaN \n",
"4 NaN "
]
},
"execution_count": 30,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# Loop through the competition files for the selected competition(s)\n",
"# Take the separate JSON files each representing a match for the selected competition(s).\n",
"# The file is called matches_{competition_name}.json.\n",
"# Read the corresponding JSON matches files using the auxillary function\n",
"# Read JSON file as a pandas DataFrame\n",
"# Append the DataFrames to a list\n",
"# Finally, concatenate all the separate DataFrames into one DataFrame\n",
"\n",
"## Create empty list for DataFrames\n",
"dfs_matches = []\n",
"\n",
"## Loop through the competition files for the selected competition(s) and append DataFrame to dfs_matches list\n",
"for competition in lst_competitions:\n",
" competition_name = competition.replace(' ', '_')\n",
" file_matches = f'matches_{competition_name}.json'\n",
" json_matches = read_json_file(data_dir_wyscout + '/raw/json/matches/' + file_matches)\n",
" df_matches = pd.read_json(json_matches)\n",
" dfs_matches.append(df_matches)\n",
"\n",
"## Concatenate DataFrames to one DataFrame\n",
"df_matches = pd.concat(dfs_matches)\n",
"\n",
"\n",
"# Display DataFrame\n",
"df_matches.head()"
]
},
{
"cell_type": "code",
"execution_count": 31,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(1941, 15)"
]
},
"execution_count": 31,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df_matches.shape"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"##### Normalise nested columns"
]
},
{
"cell_type": "code",
"execution_count": 32,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"'\\n# Flatten the nested dictionaries\\ndf_matches_flat = flatten_nested_json_df(df_matches)\\n\\n# Display DataFrame\\ndf_matches_flat.head()\\n'"
]
},
"execution_count": 32,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"\"\"\"\n",
"# Flatten the nested dictionaries\n",
"df_matches_flat = flatten_nested_json_df(df_matches)\n",
"\n",
"# Display DataFrame\n",
"df_matches_flat.head()\n",
"\"\"\""
]
},
{
"cell_type": "code",
"execution_count": 33,
"metadata": {},
"outputs": [],
"source": [
"df_matches_flat = df_matches"
]
},
{
"cell_type": "code",
"execution_count": 34,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(1941, 15)"
]
},
"execution_count": 34,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df_matches_flat.shape"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"##### Rename columns"
]
},
{
"cell_type": "code",
"execution_count": 35,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"/opt/anaconda3/lib/python3.7/site-packages/ipykernel_launcher.py:2: FutureWarning: The default value of regex will change from True to False in a future version.\n",
" \n"
]
}
],
"source": [
"# Rename column\n",
"df_matches_flat.columns = df_matches_flat.columns.str.replace('[.]', '_')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"##### Streamline the DataFrame\n",
"The `Matches` data includes a lot of `teamsData` columns that we don't require at this stage and make the DataFrame quite bulky. We will streamline this DataFrame to only include the columns of interest."
]
},
{
"cell_type": "code",
"execution_count": 36,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"Index(['status', 'roundId', 'gameweek', 'teamsData', 'seasonId', 'dateutc',\n",
" 'winner', 'venue', 'wyId', 'label', 'date', 'referees', 'duration',\n",
" 'competitionId', 'groupName'],\n",
" dtype='object')"
]
},
"execution_count": 36,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# Display DataFrame columns\n",
"df_matches_flat.columns"
]
},
{
"cell_type": "code",
"execution_count": 37,
"metadata": {},
"outputs": [],
"source": [
"# Select columns of interest\n",
"cols_matches = ['status',\n",
" 'roundId',\n",
" 'gameweek',\n",
" 'seasonId',\n",
" 'dateutc',\n",
" 'winner',\n",
" 'venue',\n",
" 'wyId',\n",
" 'label',\n",
" 'date',\n",
" 'referees',\n",
" 'duration',\n",
" 'competitionId'\n",
" ]\n",
"\n",
"# Create more concise DataFrame using only columns of interest\n",
"df_matches_flat_select = df_matches_flat[cols_matches]"
]
},
{
"cell_type": "code",
"execution_count": 38,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(1941, 13)"
]
},
"execution_count": 38,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df_matches_flat_select.shape"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"##### Export DataFrame"
]
},
{
"cell_type": "code",
"execution_count": 39,
"metadata": {},
"outputs": [],
"source": [
"# Export DataFrame as a CSV file\n",
"if not os.path.exists(os.path.join(data_dir_wyscout, 'raw', 'csv', 'matches.csv')):\n",
" df_matches_flat.to_csv(os.path.join(data_dir_wyscout, 'raw', 'csv', 'matches.csv'), index=None, header=True)\n",
"else:\n",
" pass"
]
},
{
"cell_type": "code",
"execution_count": 40,
"metadata": {},
"outputs": [],
"source": [
"# Export DataFrame as a CSV file\n",
"if not os.path.exists(os.path.join(data_dir_wyscout, 'raw', 'csv', 'matches_select.csv')):\n",
" df_matches_flat_select.to_csv(os.path.join(data_dir_wyscout, 'raw', 'csv', 'matches_select.csv'), index=None, header=True)\n",
"else:\n",
" pass"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### 3.3.4. Events \n",
"The following cells read the `events.json` files for the selected competitions into a `DataFrame` object."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"##### Data Dictionary\n",
"The [Wyscout](https://wyscout.com/) Events dataset has twelve features (columns) with the following definitions and data types:\n",
"\n",
"| Feature | Data type |\n",
"|------|-----|\n",
"| `eventId` | int64 |\n",
"| `subEventName` | object |\n",
"| `tags` | object |\n",
"| `playerId` | int64 |\n",
"| `positions` | object |\n",
"| `matchId` | int64 |\n",
"| `eventName` | object |\n",
"| `teamId` | int64 |\n",
"| `matchPeriod` | object |\n",
"| `eventSec` | float64 |\n",
"| `subEventId` | object |\n",
"| `id` | int64 |\n",
"\n",
"Refer to the Wyscout [API docs](https://apidocs.wyscout.com/) and [Events Manual](https://footballdata.wyscout.com/wp-content/uploads/2018/03/Wyscout-Events-Manual.pdf) for further information about event and subevents."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"##### Read JSON files"
]
},
{
"cell_type": "code",
"execution_count": 41,
"metadata": {
"scrolled": true
},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" \n",
" eventId \n",
" subEventName \n",
" tags \n",
" playerId \n",
" positions \n",
" matchId \n",
" eventName \n",
" teamId \n",
" matchPeriod \n",
" eventSec \n",
" subEventId \n",
" id \n",
" \n",
" \n",
" \n",
" \n",
" 0 \n",
" 8 \n",
" Simple pass \n",
" [{'id': 1801}] \n",
" 25413 \n",
" [{'y': 49, 'x': 49}, {'y': 78, 'x': 31}] \n",
" 2499719 \n",
" Pass \n",
" 1609 \n",
" 1H \n",
" 2.758649 \n",
" 85 \n",
" 177959171 \n",
" \n",
" \n",
" 1 \n",
" 8 \n",
" High pass \n",
" [{'id': 1801}] \n",
" 370224 \n",
" [{'y': 78, 'x': 31}, {'y': 75, 'x': 51}] \n",
" 2499719 \n",
" Pass \n",
" 1609 \n",
" 1H \n",
" 4.946850 \n",
" 83 \n",
" 177959172 \n",
" \n",
" \n",
" 2 \n",
" 8 \n",
" Head pass \n",
" [{'id': 1801}] \n",
" 3319 \n",
" [{'y': 75, 'x': 51}, {'y': 71, 'x': 35}] \n",
" 2499719 \n",
" Pass \n",
" 1609 \n",
" 1H \n",
" 6.542188 \n",
" 82 \n",
" 177959173 \n",
" \n",
" \n",
" 3 \n",
" 8 \n",
" Head pass \n",
" [{'id': 1801}] \n",
" 120339 \n",
" [{'y': 71, 'x': 35}, {'y': 95, 'x': 41}] \n",
" 2499719 \n",
" Pass \n",
" 1609 \n",
" 1H \n",
" 8.143395 \n",
" 82 \n",
" 177959174 \n",
" \n",
" \n",
" 4 \n",
" 8 \n",
" Simple pass \n",
" [{'id': 1801}] \n",
" 167145 \n",
" [{'y': 95, 'x': 41}, {'y': 88, 'x': 72}] \n",
" 2499719 \n",
" Pass \n",
" 1609 \n",
" 1H \n",
" 10.302366 \n",
" 85 \n",
" 177959175 \n",
" \n",
" \n",
"
\n",
"
"
],
"text/plain": [
" eventId subEventName tags playerId \\\n",
"0 8 Simple pass [{'id': 1801}] 25413 \n",
"1 8 High pass [{'id': 1801}] 370224 \n",
"2 8 Head pass [{'id': 1801}] 3319 \n",
"3 8 Head pass [{'id': 1801}] 120339 \n",
"4 8 Simple pass [{'id': 1801}] 167145 \n",
"\n",
" positions matchId eventName teamId \\\n",
"0 [{'y': 49, 'x': 49}, {'y': 78, 'x': 31}] 2499719 Pass 1609 \n",
"1 [{'y': 78, 'x': 31}, {'y': 75, 'x': 51}] 2499719 Pass 1609 \n",
"2 [{'y': 75, 'x': 51}, {'y': 71, 'x': 35}] 2499719 Pass 1609 \n",
"3 [{'y': 71, 'x': 35}, {'y': 95, 'x': 41}] 2499719 Pass 1609 \n",
"4 [{'y': 95, 'x': 41}, {'y': 88, 'x': 72}] 2499719 Pass 1609 \n",
"\n",
" matchPeriod eventSec subEventId id \n",
"0 1H 2.758649 85 177959171 \n",
"1 1H 4.946850 83 177959172 \n",
"2 1H 6.542188 82 177959173 \n",
"3 1H 8.143395 82 177959174 \n",
"4 1H 10.302366 85 177959175 "
]
},
"execution_count": 41,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# Loop through the competitions selected\n",
"# Read the corresponding events JSON files using the auxillary function\n",
"# Read JSON file as a pandas DataFrame\n",
"# Group the match events by match_id such that we end up with a separate DataFrame for each individual match\n",
"# Loop through each of the match DataFrames and read JSON file as a pandas DataFrame\n",
"# Append the DataFrames to a list\n",
"# Finally, concatenate all the separate DataFrames into one DataFrame\n",
"\n",
"## Create empty list for DataFrames\n",
"dfs_events = []\n",
"\n",
"## Loop through the competition files for the selected competition(s) and append DataFrame to dfs_events list\n",
"for competition in competitions:\n",
" competition_name = competition.replace(' ', '_')\n",
" file_events = f'events_{competition_name}.json'\n",
" json_events = read_json_file(data_dir_wyscout + '/raw/json/events/' + file_events)\n",
" df_events = pd.read_json(json_events)\n",
" dfs_events.append(df_events)\n",
" #df_events_matches = df_events.groupby('matchId', as_index=False)\n",
"\n",
"## Concatenate DataFrames to one DataFrame\n",
"df_events = pd.concat(dfs_events)\n",
"\n",
"\n",
"# Display DataFrame\n",
"df_events.head()"
]
},
{
"cell_type": "code",
"execution_count": 42,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(3251294, 12)"
]
},
"execution_count": 42,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df_events.shape"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"##### Normalise nested columns"
]
},
{
"cell_type": "code",
"execution_count": 43,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"'\\n# Flatten the nested dictionaries\\ndf_events_flat = flatten_nested_json_df(df_events)\\n\\n# Display DataFrame\\ndf_events_flat.head()\\n'"
]
},
"execution_count": 43,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"\"\"\"\n",
"# Flatten the nested dictionaries\n",
"df_events_flat = flatten_nested_json_df(df_events)\n",
"\n",
"# Display DataFrame\n",
"df_events_flat.head()\n",
"\"\"\""
]
},
{
"cell_type": "code",
"execution_count": 44,
"metadata": {},
"outputs": [],
"source": [
"df_events_flat = df_events"
]
},
{
"cell_type": "code",
"execution_count": 45,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(3251294, 12)"
]
},
"execution_count": 45,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df_events_flat.shape"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"##### Rename columns"
]
},
{
"cell_type": "code",
"execution_count": 46,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"/opt/anaconda3/lib/python3.7/site-packages/ipykernel_launcher.py:2: FutureWarning: The default value of regex will change from True to False in a future version.\n",
" \n"
]
}
],
"source": [
"# Rename column\n",
"df_events_flat.columns = df_events_flat.columns.str.replace('[.]', '_')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"##### Separate `positions` column into four individual columns\n",
"Not the nicest code, but I found issues with the apply function, and this works fine."
]
},
{
"cell_type": "code",
"execution_count": 51,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"/opt/anaconda3/lib/python3.7/site-packages/ipykernel_launcher.py:1: FutureWarning: The default value of regex will change from True to False in a future version. In addition, single character regular expressions will*not* be treated as literal strings when regex=True.\n",
" \"\"\"Entry point for launching an IPython kernel.\n",
"/opt/anaconda3/lib/python3.7/site-packages/ipykernel_launcher.py:2: FutureWarning: The default value of regex will change from True to False in a future version. In addition, single character regular expressions will*not* be treated as literal strings when regex=True.\n",
" \n",
"/opt/anaconda3/lib/python3.7/site-packages/ipykernel_launcher.py:3: FutureWarning: The default value of regex will change from True to False in a future version.\n",
" This is separate from the ipykernel package so we can avoid doing imports until\n",
"/opt/anaconda3/lib/python3.7/site-packages/ipykernel_launcher.py:4: FutureWarning: The default value of regex will change from True to False in a future version.\n",
" after removing the cwd from sys.path.\n",
"/opt/anaconda3/lib/python3.7/site-packages/ipykernel_launcher.py:7: FutureWarning: The default value of regex will change from True to False in a future version. In addition, single character regular expressions will*not* be treated as literal strings when regex=True.\n",
" import sys\n"
]
}
],
"source": [
"\"\"\"\n",
"# Convert positions column that contains a nested dictionary to a string\n",
"df_events_flat['positions'] = df_events_flat['positions'].astype(str)\n",
"\n",
"# Replace all the values in the dictionary, only leaving coordinates and comma separater\n",
"df_events_flat['positions'] = df_events_flat['positions'].str.replace('[','')\n",
"df_events_flat['positions'] = df_events_flat['positions'].str.replace(']','')\n",
"df_events_flat['positions'] = df_events_flat['positions'].str.replace('}, {',', ')\n",
"df_events_flat['positions'] = df_events_flat['positions'].str.replace(\"{\\'y\\': \", \"\")\n",
"df_events_flat['positions'] = df_events_flat['positions'].str.replace(\", 'x': \", \", \")\n",
"df_events_flat['positions'] = df_events_flat['positions'].str.replace(\", 'y':\", \", \")\n",
"df_events_flat['positions'] = df_events_flat['positions'].str.replace(\"}\", \"\")\n",
"\n",
"df_events_flat[['x_before', 'y_before', 'x_after', 'y_after']] = df_events_flat['positions'].str.split(',', expand=True)\n",
"\n",
"\"\"\""
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"##### Streamline the DataFrame"
]
},
{
"cell_type": "code",
"execution_count": 48,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"Index(['eventId', 'subEventName', 'tags', 'playerId', 'positions', 'matchId',\n",
" 'eventName', 'teamId', 'matchPeriod', 'eventSec', 'subEventId', 'id'],\n",
" dtype='object')"
]
},
"execution_count": 48,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# Display DataFrame columns\n",
"df_events_flat.columns"
]
},
{
"cell_type": "code",
"execution_count": 49,
"metadata": {},
"outputs": [],
"source": [
"# Select columns of interest\n",
"cols_events = ['eventId',\n",
" 'subEventName',\n",
" 'playerId',\n",
" 'positions',\n",
" 'matchId',\n",
" 'eventName',\n",
" 'teamId',\n",
" 'matchPeriod',\n",
" 'eventSec',\n",
" 'subEventId',\n",
" 'id',\n",
" 'tags'\n",
" ]\n",
"\n",
"# Create more concise DataFrame using only columns of interest\n",
"df_events_flat_select = df_events_flat[cols_events]"
]
},
{
"cell_type": "code",
"execution_count": 50,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(3251294, 12)"
]
},
"execution_count": 50,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df_events_flat_select.shape"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"##### Export DataFrame"
]
},
{
"cell_type": "code",
"execution_count": 51,
"metadata": {},
"outputs": [],
"source": [
"# Export DataFrame as a CSV file\n",
"if not os.path.exists(os.path.join(data_dir_wyscout, 'raw', 'csv', 'events.csv')):\n",
" df_events_flat.to_csv(os.path.join(data_dir_wyscout, 'raw', 'csv', 'events.csv'), index=None, header=True)\n",
"else:\n",
" pass"
]
},
{
"cell_type": "code",
"execution_count": 52,
"metadata": {},
"outputs": [],
"source": [
"# Export DataFrame as a CSV file\n",
"if not os.path.exists(os.path.join(data_dir_wyscout, 'raw', 'csv', 'events_select.csv')):\n",
" df_events_flat_select.to_csv(os.path.join(data_dir_wyscout, 'raw', 'csv', 'events_select.csv'), index=None, header=True)\n",
"else:\n",
" pass"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### 3.3.5 Competitions "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"##### Data Dictionary\n",
"The [Wyscout](https://wyscout.com/) Events dataset has twelve features (columns) with the following definitions and data types:\n",
"\n",
"| Feature | Data type |\n",
"|------|-----|\n",
"| `eventId` | int64 |\n",
"| `subEventName` | object |\n",
"| `tags` | object |\n",
"| `playerId` | int64 |\n",
"| `positions` | object |\n",
"| `matchId` | int64 |\n",
"| `eventName` | object |\n",
"| `teamId` | int64 |\n",
"| `matchPeriod` | object |\n",
"| `eventSec` | float64 |\n",
"| `subEventId` | object |\n",
"| `id` | int64 |\n",
"\n",
"Refer to the Wyscout [API docs](https://apidocs.wyscout.com/) and [Events Manual](https://footballdata.wyscout.com/wp-content/uploads/2018/03/Wyscout-Events-Manual.pdf) for further information about events and subevents."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"##### Read JSON file"
]
},
{
"cell_type": "code",
"execution_count": 53,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" \n",
" name \n",
" wyId \n",
" format \n",
" area \n",
" type \n",
" \n",
" \n",
" \n",
" \n",
" 0 \n",
" Italian first division \n",
" 524 \n",
" Domestic league \n",
" {'name': 'Italy', 'id': '380', 'alpha3code': '... \n",
" club \n",
" \n",
" \n",
" 1 \n",
" English first division \n",
" 364 \n",
" Domestic league \n",
" {'name': 'England', 'id': '0', 'alpha3code': '... \n",
" club \n",
" \n",
" \n",
" 2 \n",
" Spanish first division \n",
" 795 \n",
" Domestic league \n",
" {'name': 'Spain', 'id': '724', 'alpha3code': '... \n",
" club \n",
" \n",
" \n",
" 3 \n",
" French first division \n",
" 412 \n",
" Domestic league \n",
" {'name': 'France', 'id': '250', 'alpha3code': ... \n",
" club \n",
" \n",
" \n",
" 4 \n",
" German first division \n",
" 426 \n",
" Domestic league \n",
" {'name': 'Germany', 'id': '276', 'alpha3code':... \n",
" club \n",
" \n",
" \n",
"
\n",
"
"
],
"text/plain": [
" name wyId format \\\n",
"0 Italian first division 524 Domestic league \n",
"1 English first division 364 Domestic league \n",
"2 Spanish first division 795 Domestic league \n",
"3 French first division 412 Domestic league \n",
"4 German first division 426 Domestic league \n",
"\n",
" area type \n",
"0 {'name': 'Italy', 'id': '380', 'alpha3code': '... club \n",
"1 {'name': 'England', 'id': '0', 'alpha3code': '... club \n",
"2 {'name': 'Spain', 'id': '724', 'alpha3code': '... club \n",
"3 {'name': 'France', 'id': '250', 'alpha3code': ... club \n",
"4 {'name': 'Germany', 'id': '276', 'alpha3code':... club "
]
},
"execution_count": 53,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# Read JSON file as a JSON string and create a pandas DataFrame form the resulting JSON string\n",
"json_competitions = read_json_file(data_dir_wyscout + '/raw/json/' + 'competitions.json')\n",
"df_competitions = pd.read_json(json_competitions)\n",
"\n",
"# Display DataFrame\n",
"df_competitions.head()"
]
},
{
"cell_type": "code",
"execution_count": 54,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(7, 5)"
]
},
"execution_count": 54,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df_competitions.shape"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"##### Normalise nested columns"
]
},
{
"cell_type": "code",
"execution_count": 55,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"original shape: (7, 6)\n",
"original columns: Index(['index', 'name', 'wyId', 'format', 'area', 'type'], dtype='object')\n",
"lists: [], dicts: ['area']\n",
"flattening: area\n",
"lists: [], dicts: []\n",
"final shape: (7, 9)\n",
"final columns: Index(['index', 'name', 'wyId', 'format', 'type', 'area.name', 'area.id',\n",
" 'area.alpha3code', 'area.alpha2code'],\n",
" dtype='object')\n"
]
},
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" \n",
" index \n",
" name \n",
" wyId \n",
" format \n",
" type \n",
" area.name \n",
" area.id \n",
" area.alpha3code \n",
" area.alpha2code \n",
" \n",
" \n",
" \n",
" \n",
" 0 \n",
" 0 \n",
" Italian first division \n",
" 524 \n",
" Domestic league \n",
" club \n",
" Italy \n",
" 380 \n",
" ITA \n",
" IT \n",
" \n",
" \n",
" 1 \n",
" 1 \n",
" English first division \n",
" 364 \n",
" Domestic league \n",
" club \n",
" England \n",
" 0 \n",
" XEN \n",
" \n",
" \n",
" \n",
" 2 \n",
" 2 \n",
" Spanish first division \n",
" 795 \n",
" Domestic league \n",
" club \n",
" Spain \n",
" 724 \n",
" ESP \n",
" ES \n",
" \n",
" \n",
" 3 \n",
" 3 \n",
" French first division \n",
" 412 \n",
" Domestic league \n",
" club \n",
" France \n",
" 250 \n",
" FRA \n",
" FR \n",
" \n",
" \n",
" 4 \n",
" 4 \n",
" German first division \n",
" 426 \n",
" Domestic league \n",
" club \n",
" Germany \n",
" 276 \n",
" DEU \n",
" DE \n",
" \n",
" \n",
"
\n",
"
"
],
"text/plain": [
" index name wyId format type area.name \\\n",
"0 0 Italian first division 524 Domestic league club Italy \n",
"1 1 English first division 364 Domestic league club England \n",
"2 2 Spanish first division 795 Domestic league club Spain \n",
"3 3 French first division 412 Domestic league club France \n",
"4 4 German first division 426 Domestic league club Germany \n",
"\n",
" area.id area.alpha3code area.alpha2code \n",
"0 380 ITA IT \n",
"1 0 XEN \n",
"2 724 ESP ES \n",
"3 250 FRA FR \n",
"4 276 DEU DE "
]
},
"execution_count": 55,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# Flatten the nested dictionaries\n",
"df_competitions_flat = flatten_nested_json_df(df_competitions)\n",
"\n",
"# Display DataFrame\n",
"df_competitions_flat.head()"
]
},
{
"cell_type": "code",
"execution_count": 56,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(7, 9)"
]
},
"execution_count": 56,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df_competitions_flat.shape"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"##### Rename columns"
]
},
{
"cell_type": "code",
"execution_count": 57,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"/opt/anaconda3/lib/python3.7/site-packages/ipykernel_launcher.py:2: FutureWarning: The default value of regex will change from True to False in a future version.\n",
" \n"
]
}
],
"source": [
"# Rename column\n",
"df_competitions_flat.columns = df_competitions_flat.columns.str.replace('[.]', '_')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"##### Streamline the DataFrame"
]
},
{
"cell_type": "code",
"execution_count": 58,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"Index(['index', 'name', 'wyId', 'format', 'type', 'area_name', 'area_id',\n",
" 'area_alpha3code', 'area_alpha2code'],\n",
" dtype='object')"
]
},
"execution_count": 58,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# Display DataFrame columns\n",
"df_competitions_flat.columns"
]
},
{
"cell_type": "code",
"execution_count": 59,
"metadata": {},
"outputs": [],
"source": [
"# Select columns of interest\n",
"cols_competitions = ['wyId',\n",
" 'area_name'\n",
" ]\n",
"\n",
"# Create more concise DataFrame using only columns of interest\n",
"df_competitions_flat_select = df_competitions_flat[cols_competitions]"
]
},
{
"cell_type": "code",
"execution_count": 60,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(7, 2)"
]
},
"execution_count": 60,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df_competitions_flat_select.shape"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"##### Export DataFrame"
]
},
{
"cell_type": "code",
"execution_count": 61,
"metadata": {},
"outputs": [],
"source": [
"# Export DataFrame as a CSV file\n",
"if not os.path.exists(os.path.join(data_dir_wyscout, 'raw', 'csv', 'competitions.csv')):\n",
" df_competitions_flat.to_csv(os.path.join(data_dir_wyscout, 'raw', 'csv', 'competitions.csv'), index=None, header=True)\n",
"else:\n",
" pass"
]
},
{
"cell_type": "code",
"execution_count": 62,
"metadata": {},
"outputs": [],
"source": [
"# Export DataFrame as a CSV file\n",
"if not os.path.exists(os.path.join(data_dir_wyscout, 'raw', 'csv', 'competitions_select.csv')):\n",
" df_competitions_flat_select.to_csv(os.path.join(data_dir_wyscout, 'raw', 'csv', 'competitions_select.csv'), index=None, header=True)\n",
"else:\n",
" pass"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 3.4. Join Datasets \n",
"Next, we're required to join the `Matches` DataFrame and the `Players` DataFrame to the `Events` DatFrame. The `Events` data is the base DataFrame in which we join the other tables via `wyId`, `matchId`, `competitionId`, `playerId`, and `teamId`."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"##### Join Matches DataFrame to Events DataFrame"
]
},
{
"cell_type": "code",
"execution_count": 63,
"metadata": {},
"outputs": [],
"source": [
"# Join the Events DataFrame to the Matches DataFrame\n",
"df_wyscout_merge = pd.merge(df_events_flat_select, df_matches_flat_select, left_on='matchId', right_on='wyId')"
]
},
{
"cell_type": "code",
"execution_count": 64,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(3251294, 12)"
]
},
"execution_count": 64,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df_events_flat_select.shape"
]
},
{
"cell_type": "code",
"execution_count": 65,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(3251294, 25)"
]
},
"execution_count": 65,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df_wyscout_merge.shape"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"##### Join Competitions DataFrame to Merged DataFrame via Events DataFrame"
]
},
{
"cell_type": "code",
"execution_count": 66,
"metadata": {},
"outputs": [],
"source": [
"# Join the Competitions DataFrame to the Events-Matches DataFrame\n",
"df_wyscout_merge = pd.merge(df_wyscout_merge, df_competitions_flat_select, left_on='competitionId', right_on='wyId')"
]
},
{
"cell_type": "code",
"execution_count": 67,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(3251294, 27)"
]
},
"execution_count": 67,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df_wyscout_merge.shape"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"##### Join Players DataFrame to Merged DataFrame via Events DataFrame"
]
},
{
"cell_type": "code",
"execution_count": 68,
"metadata": {},
"outputs": [],
"source": [
"# Join the Players DataFrame to the Events-Matches-Competitions DataFrame\n",
"df_wyscout_merge = pd.merge(df_wyscout_merge, df_players_flat_select, left_on='playerId', right_on='wyId')"
]
},
{
"cell_type": "code",
"execution_count": 69,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(3025256, 39)"
]
},
"execution_count": 69,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df_wyscout_merge.shape"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"##### Join Teams DataFrame to Merged DataFrame via Events DataFrame"
]
},
{
"cell_type": "code",
"execution_count": 70,
"metadata": {},
"outputs": [],
"source": [
"# Join the Players DataFrame to the Events-Matches-Players DataFrame\n",
"df_wyscout_merge = pd.merge(df_wyscout_merge, df_teams_flat_select, left_on='teamId', right_on='wyId')"
]
},
{
"cell_type": "code",
"execution_count": 71,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(3025256, 41)"
]
},
"execution_count": 71,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df_wyscout_merge.shape"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 3.5. Initial Data Handling \n",
"Let's quality of the dataset by looking first and last rows in pandas using the [head()](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.head.html) and [tail()](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.tail.html) methods."
]
},
{
"cell_type": "code",
"execution_count": 72,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" \n",
" eventId \n",
" subEventName \n",
" playerId \n",
" positions \n",
" matchId \n",
" eventName \n",
" teamId \n",
" matchPeriod \n",
" eventSec \n",
" subEventId \n",
" id \n",
" tags \n",
" status \n",
" roundId \n",
" gameweek \n",
" seasonId \n",
" dateutc \n",
" winner \n",
" venue \n",
" wyId_x \n",
" label \n",
" date \n",
" referees \n",
" duration \n",
" competitionId \n",
" wyId_y \n",
" area_name \n",
" weight \n",
" firstName \n",
" middleName \n",
" lastName \n",
" birthDate \n",
" height \n",
" wyId_x \n",
" foot \n",
" shortName \n",
" passportArea_name \n",
" role_name \n",
" birthArea_name \n",
" name \n",
" wyId_y \n",
" \n",
" \n",
" \n",
" \n",
" 0 \n",
" 8 \n",
" Simple pass \n",
" 25413 \n",
" [{'y': 49, 'x': 49}, {'y': 78, 'x': 31}] \n",
" 2499719 \n",
" Pass \n",
" 1609 \n",
" 1H \n",
" 2.758649 \n",
" 85 \n",
" 177959171 \n",
" [{'id': 1801}] \n",
" Played \n",
" 4405654 \n",
" 1 \n",
" 181150 \n",
" 2017-08-11 18:45:00 \n",
" 1609 \n",
" Emirates Stadium \n",
" 2499719 \n",
" Arsenal - Leicester City, 4 - 3 \n",
" August 11, 2017 at 8:45:00 PM GMT+2 \n",
" [{'refereeId': 385909, 'role': 'referee'}, {'r... \n",
" Regular \n",
" 364 \n",
" 364 \n",
" England \n",
" 73 \n",
" Alexandre \n",
" \n",
" Lacazette \n",
" 1991-05-28 \n",
" 175 \n",
" 25413 \n",
" right \n",
" A. Lacazette \n",
" Guadeloupe \n",
" Forward \n",
" France \n",
" Arsenal \n",
" 1609 \n",
" \n",
" \n",
" 1 \n",
" 1 \n",
" Air duel \n",
" 25413 \n",
" [{'y': 54, 'x': 71}, {'y': 59, 'x': 50}] \n",
" 2499719 \n",
" Duel \n",
" 1609 \n",
" 1H \n",
" 22.551816 \n",
" 10 \n",
" 177959181 \n",
" [{'id': 701}, {'id': 1802}] \n",
" Played \n",
" 4405654 \n",
" 1 \n",
" 181150 \n",
" 2017-08-11 18:45:00 \n",
" 1609 \n",
" Emirates Stadium \n",
" 2499719 \n",
" Arsenal - Leicester City, 4 - 3 \n",
" August 11, 2017 at 8:45:00 PM GMT+2 \n",
" [{'refereeId': 385909, 'role': 'referee'}, {'r... \n",
" Regular \n",
" 364 \n",
" 364 \n",
" England \n",
" 73 \n",
" Alexandre \n",
" \n",
" Lacazette \n",
" 1991-05-28 \n",
" 175 \n",
" 25413 \n",
" right \n",
" A. Lacazette \n",
" Guadeloupe \n",
" Forward \n",
" France \n",
" Arsenal \n",
" 1609 \n",
" \n",
" \n",
" 2 \n",
" 10 \n",
" Shot \n",
" 25413 \n",
" [{'y': 41, 'x': 88}, {'y': 0, 'x': 0}] \n",
" 2499719 \n",
" Shot \n",
" 1609 \n",
" 1H \n",
" 94.595788 \n",
" 100 \n",
" 177959212 \n",
" [{'id': 101}, {'id': 402}, {'id': 201}, {'id':... \n",
" Played \n",
" 4405654 \n",
" 1 \n",
" 181150 \n",
" 2017-08-11 18:45:00 \n",
" 1609 \n",
" Emirates Stadium \n",
" 2499719 \n",
" Arsenal - Leicester City, 4 - 3 \n",
" August 11, 2017 at 8:45:00 PM GMT+2 \n",
" [{'refereeId': 385909, 'role': 'referee'}, {'r... \n",
" Regular \n",
" 364 \n",
" 364 \n",
" England \n",
" 73 \n",
" Alexandre \n",
" \n",
" Lacazette \n",
" 1991-05-28 \n",
" 175 \n",
" 25413 \n",
" right \n",
" A. Lacazette \n",
" Guadeloupe \n",
" Forward \n",
" France \n",
" Arsenal \n",
" 1609 \n",
" \n",
" \n",
" 3 \n",
" 8 \n",
" Head pass \n",
" 25413 \n",
" [{'y': 70, 'x': 71}, {'y': 63, 'x': 71}] \n",
" 2499719 \n",
" Pass \n",
" 1609 \n",
" 1H \n",
" 397.881307 \n",
" 82 \n",
" 177959276 \n",
" [{'id': 1802}] \n",
" Played \n",
" 4405654 \n",
" 1 \n",
" 181150 \n",
" 2017-08-11 18:45:00 \n",
" 1609 \n",
" Emirates Stadium \n",
" 2499719 \n",
" Arsenal - Leicester City, 4 - 3 \n",
" August 11, 2017 at 8:45:00 PM GMT+2 \n",
" [{'refereeId': 385909, 'role': 'referee'}, {'r... \n",
" Regular \n",
" 364 \n",
" 364 \n",
" England \n",
" 73 \n",
" Alexandre \n",
" \n",
" Lacazette \n",
" 1991-05-28 \n",
" 175 \n",
" 25413 \n",
" right \n",
" A. Lacazette \n",
" Guadeloupe \n",
" Forward \n",
" France \n",
" Arsenal \n",
" 1609 \n",
" \n",
" \n",
" 4 \n",
" 1 \n",
" Ground defending duel \n",
" 25413 \n",
" [{'y': 64, 'x': 61}, {'y': 87, 'x': 51}] \n",
" 2499719 \n",
" Duel \n",
" 1609 \n",
" 1H \n",
" 494.461238 \n",
" 12 \n",
" 177959303 \n",
" [{'id': 503}, {'id': 701}, {'id': 1802}] \n",
" Played \n",
" 4405654 \n",
" 1 \n",
" 181150 \n",
" 2017-08-11 18:45:00 \n",
" 1609 \n",
" Emirates Stadium \n",
" 2499719 \n",
" Arsenal - Leicester City, 4 - 3 \n",
" August 11, 2017 at 8:45:00 PM GMT+2 \n",
" [{'refereeId': 385909, 'role': 'referee'}, {'r... \n",
" Regular \n",
" 364 \n",
" 364 \n",
" England \n",
" 73 \n",
" Alexandre \n",
" \n",
" Lacazette \n",
" 1991-05-28 \n",
" 175 \n",
" 25413 \n",
" right \n",
" A. Lacazette \n",
" Guadeloupe \n",
" Forward \n",
" France \n",
" Arsenal \n",
" 1609 \n",
" \n",
" \n",
"
\n",
"
"
],
"text/plain": [
" eventId subEventName playerId \\\n",
"0 8 Simple pass 25413 \n",
"1 1 Air duel 25413 \n",
"2 10 Shot 25413 \n",
"3 8 Head pass 25413 \n",
"4 1 Ground defending duel 25413 \n",
"\n",
" positions matchId eventName teamId \\\n",
"0 [{'y': 49, 'x': 49}, {'y': 78, 'x': 31}] 2499719 Pass 1609 \n",
"1 [{'y': 54, 'x': 71}, {'y': 59, 'x': 50}] 2499719 Duel 1609 \n",
"2 [{'y': 41, 'x': 88}, {'y': 0, 'x': 0}] 2499719 Shot 1609 \n",
"3 [{'y': 70, 'x': 71}, {'y': 63, 'x': 71}] 2499719 Pass 1609 \n",
"4 [{'y': 64, 'x': 61}, {'y': 87, 'x': 51}] 2499719 Duel 1609 \n",
"\n",
" matchPeriod eventSec subEventId id \\\n",
"0 1H 2.758649 85 177959171 \n",
"1 1H 22.551816 10 177959181 \n",
"2 1H 94.595788 100 177959212 \n",
"3 1H 397.881307 82 177959276 \n",
"4 1H 494.461238 12 177959303 \n",
"\n",
" tags status roundId \\\n",
"0 [{'id': 1801}] Played 4405654 \n",
"1 [{'id': 701}, {'id': 1802}] Played 4405654 \n",
"2 [{'id': 101}, {'id': 402}, {'id': 201}, {'id':... Played 4405654 \n",
"3 [{'id': 1802}] Played 4405654 \n",
"4 [{'id': 503}, {'id': 701}, {'id': 1802}] Played 4405654 \n",
"\n",
" gameweek seasonId dateutc winner venue wyId_x \\\n",
"0 1 181150 2017-08-11 18:45:00 1609 Emirates Stadium 2499719 \n",
"1 1 181150 2017-08-11 18:45:00 1609 Emirates Stadium 2499719 \n",
"2 1 181150 2017-08-11 18:45:00 1609 Emirates Stadium 2499719 \n",
"3 1 181150 2017-08-11 18:45:00 1609 Emirates Stadium 2499719 \n",
"4 1 181150 2017-08-11 18:45:00 1609 Emirates Stadium 2499719 \n",
"\n",
" label date \\\n",
"0 Arsenal - Leicester City, 4 - 3 August 11, 2017 at 8:45:00 PM GMT+2 \n",
"1 Arsenal - Leicester City, 4 - 3 August 11, 2017 at 8:45:00 PM GMT+2 \n",
"2 Arsenal - Leicester City, 4 - 3 August 11, 2017 at 8:45:00 PM GMT+2 \n",
"3 Arsenal - Leicester City, 4 - 3 August 11, 2017 at 8:45:00 PM GMT+2 \n",
"4 Arsenal - Leicester City, 4 - 3 August 11, 2017 at 8:45:00 PM GMT+2 \n",
"\n",
" referees duration competitionId \\\n",
"0 [{'refereeId': 385909, 'role': 'referee'}, {'r... Regular 364 \n",
"1 [{'refereeId': 385909, 'role': 'referee'}, {'r... Regular 364 \n",
"2 [{'refereeId': 385909, 'role': 'referee'}, {'r... Regular 364 \n",
"3 [{'refereeId': 385909, 'role': 'referee'}, {'r... Regular 364 \n",
"4 [{'refereeId': 385909, 'role': 'referee'}, {'r... Regular 364 \n",
"\n",
" wyId_y area_name weight firstName middleName lastName birthDate \\\n",
"0 364 England 73 Alexandre Lacazette 1991-05-28 \n",
"1 364 England 73 Alexandre Lacazette 1991-05-28 \n",
"2 364 England 73 Alexandre Lacazette 1991-05-28 \n",
"3 364 England 73 Alexandre Lacazette 1991-05-28 \n",
"4 364 England 73 Alexandre Lacazette 1991-05-28 \n",
"\n",
" height wyId_x foot shortName passportArea_name role_name \\\n",
"0 175 25413 right A. Lacazette Guadeloupe Forward \n",
"1 175 25413 right A. Lacazette Guadeloupe Forward \n",
"2 175 25413 right A. Lacazette Guadeloupe Forward \n",
"3 175 25413 right A. Lacazette Guadeloupe Forward \n",
"4 175 25413 right A. Lacazette Guadeloupe Forward \n",
"\n",
" birthArea_name name wyId_y \n",
"0 France Arsenal 1609 \n",
"1 France Arsenal 1609 \n",
"2 France Arsenal 1609 \n",
"3 France Arsenal 1609 \n",
"4 France Arsenal 1609 "
]
},
"execution_count": 72,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# Display the first 5 rows of the raw DataFrame, df_wyscout_merge\n",
"df_wyscout_merge.head()"
]
},
{
"cell_type": "code",
"execution_count": 73,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" \n",
" eventId \n",
" subEventName \n",
" playerId \n",
" positions \n",
" matchId \n",
" eventName \n",
" teamId \n",
" matchPeriod \n",
" eventSec \n",
" subEventId \n",
" id \n",
" tags \n",
" status \n",
" roundId \n",
" gameweek \n",
" seasonId \n",
" dateutc \n",
" winner \n",
" venue \n",
" wyId_x \n",
" label \n",
" date \n",
" referees \n",
" duration \n",
" competitionId \n",
" wyId_y \n",
" area_name \n",
" weight \n",
" firstName \n",
" middleName \n",
" lastName \n",
" birthDate \n",
" height \n",
" wyId_x \n",
" foot \n",
" shortName \n",
" passportArea_name \n",
" role_name \n",
" birthArea_name \n",
" name \n",
" wyId_y \n",
" \n",
" \n",
" \n",
" \n",
" 3025251 \n",
" 8 \n",
" Simple pass \n",
" 116293 \n",
" [{'y': 72, 'x': 30}, {'y': 64, 'x': 42}] \n",
" 2057995 \n",
" Pass \n",
" 17929 \n",
" 2H \n",
" 2242.045496 \n",
" 85 \n",
" 260874786 \n",
" [{'id': 1801}] \n",
" Played \n",
" 4165363 \n",
" 3 \n",
" 10078 \n",
" 2018-06-28 18:00:00 \n",
" 16276 \n",
" Mordovia Arena \n",
" 2057995 \n",
" Panama - Tunisia, 1 - 2 \n",
" 2018-06-28 20:00:00-02:00 \n",
" [{'refereeId': 380581, 'role': 'referee'}, {'r... \n",
" Regular \n",
" 28 \n",
" 28 \n",
" \n",
" 84 \n",
" Harold Oshkaly \n",
" \n",
" Cummings Segura \n",
" 1992-03-01 \n",
" 180 \n",
" 116293 \n",
" right \n",
" H. Cummings \n",
" Panama \n",
" Defender \n",
" Panama \n",
" Panama \n",
" 17929 \n",
" \n",
" \n",
" 3025252 \n",
" 1 \n",
" Ground attacking duel \n",
" 116293 \n",
" [{'y': 73, 'x': 37}, {'y': 48, 'x': 28}] \n",
" 2057995 \n",
" Duel \n",
" 17929 \n",
" 2H \n",
" 2501.224726 \n",
" 11 \n",
" 260874815 \n",
" [{'id': 504}, {'id': 703}, {'id': 1801}] \n",
" Played \n",
" 4165363 \n",
" 3 \n",
" 10078 \n",
" 2018-06-28 18:00:00 \n",
" 16276 \n",
" Mordovia Arena \n",
" 2057995 \n",
" Panama - Tunisia, 1 - 2 \n",
" 2018-06-28 20:00:00-02:00 \n",
" [{'refereeId': 380581, 'role': 'referee'}, {'r... \n",
" Regular \n",
" 28 \n",
" 28 \n",
" \n",
" 84 \n",
" Harold Oshkaly \n",
" \n",
" Cummings Segura \n",
" 1992-03-01 \n",
" 180 \n",
" 116293 \n",
" right \n",
" H. Cummings \n",
" Panama \n",
" Defender \n",
" Panama \n",
" Panama \n",
" 17929 \n",
" \n",
" \n",
" 3025253 \n",
" 1 \n",
" Air duel \n",
" 116293 \n",
" [{'y': 70, 'x': 33}, {'y': 81, 'x': 23}] \n",
" 2057995 \n",
" Duel \n",
" 17929 \n",
" 2H \n",
" 2693.694869 \n",
" 10 \n",
" 260874832 \n",
" [{'id': 701}, {'id': 1802}] \n",
" Played \n",
" 4165363 \n",
" 3 \n",
" 10078 \n",
" 2018-06-28 18:00:00 \n",
" 16276 \n",
" Mordovia Arena \n",
" 2057995 \n",
" Panama - Tunisia, 1 - 2 \n",
" 2018-06-28 20:00:00-02:00 \n",
" [{'refereeId': 380581, 'role': 'referee'}, {'r... \n",
" Regular \n",
" 28 \n",
" 28 \n",
" \n",
" 84 \n",
" Harold Oshkaly \n",
" \n",
" Cummings Segura \n",
" 1992-03-01 \n",
" 180 \n",
" 116293 \n",
" right \n",
" H. Cummings \n",
" Panama \n",
" Defender \n",
" Panama \n",
" Panama \n",
" 17929 \n",
" \n",
" \n",
" 3025254 \n",
" 8 \n",
" Simple pass \n",
" 116293 \n",
" [{'y': 52, 'x': 39}, {'y': 33, 'x': 39}] \n",
" 2057995 \n",
" Pass \n",
" 17929 \n",
" 2H \n",
" 2784.257941 \n",
" 85 \n",
" 260874843 \n",
" [{'id': 1801}] \n",
" Played \n",
" 4165363 \n",
" 3 \n",
" 10078 \n",
" 2018-06-28 18:00:00 \n",
" 16276 \n",
" Mordovia Arena \n",
" 2057995 \n",
" Panama - Tunisia, 1 - 2 \n",
" 2018-06-28 20:00:00-02:00 \n",
" [{'refereeId': 380581, 'role': 'referee'}, {'r... \n",
" Regular \n",
" 28 \n",
" 28 \n",
" \n",
" 84 \n",
" Harold Oshkaly \n",
" \n",
" Cummings Segura \n",
" 1992-03-01 \n",
" 180 \n",
" 116293 \n",
" right \n",
" H. Cummings \n",
" Panama \n",
" Defender \n",
" Panama \n",
" Panama \n",
" 17929 \n",
" \n",
" \n",
" 3025255 \n",
" 8 \n",
" High pass \n",
" 116293 \n",
" [{'y': 65, 'x': 35}, {'y': 82, 'x': 69}] \n",
" 2057995 \n",
" Pass \n",
" 17929 \n",
" 2H \n",
" 2792.161774 \n",
" 83 \n",
" 260874845 \n",
" [{'id': 1802}] \n",
" Played \n",
" 4165363 \n",
" 3 \n",
" 10078 \n",
" 2018-06-28 18:00:00 \n",
" 16276 \n",
" Mordovia Arena \n",
" 2057995 \n",
" Panama - Tunisia, 1 - 2 \n",
" 2018-06-28 20:00:00-02:00 \n",
" [{'refereeId': 380581, 'role': 'referee'}, {'r... \n",
" Regular \n",
" 28 \n",
" 28 \n",
" \n",
" 84 \n",
" Harold Oshkaly \n",
" \n",
" Cummings Segura \n",
" 1992-03-01 \n",
" 180 \n",
" 116293 \n",
" right \n",
" H. Cummings \n",
" Panama \n",
" Defender \n",
" Panama \n",
" Panama \n",
" 17929 \n",
" \n",
" \n",
"
\n",
"
"
],
"text/plain": [
" eventId subEventName playerId \\\n",
"3025251 8 Simple pass 116293 \n",
"3025252 1 Ground attacking duel 116293 \n",
"3025253 1 Air duel 116293 \n",
"3025254 8 Simple pass 116293 \n",
"3025255 8 High pass 116293 \n",
"\n",
" positions matchId eventName teamId \\\n",
"3025251 [{'y': 72, 'x': 30}, {'y': 64, 'x': 42}] 2057995 Pass 17929 \n",
"3025252 [{'y': 73, 'x': 37}, {'y': 48, 'x': 28}] 2057995 Duel 17929 \n",
"3025253 [{'y': 70, 'x': 33}, {'y': 81, 'x': 23}] 2057995 Duel 17929 \n",
"3025254 [{'y': 52, 'x': 39}, {'y': 33, 'x': 39}] 2057995 Pass 17929 \n",
"3025255 [{'y': 65, 'x': 35}, {'y': 82, 'x': 69}] 2057995 Pass 17929 \n",
"\n",
" matchPeriod eventSec subEventId id \\\n",
"3025251 2H 2242.045496 85 260874786 \n",
"3025252 2H 2501.224726 11 260874815 \n",
"3025253 2H 2693.694869 10 260874832 \n",
"3025254 2H 2784.257941 85 260874843 \n",
"3025255 2H 2792.161774 83 260874845 \n",
"\n",
" tags status roundId gameweek \\\n",
"3025251 [{'id': 1801}] Played 4165363 3 \n",
"3025252 [{'id': 504}, {'id': 703}, {'id': 1801}] Played 4165363 3 \n",
"3025253 [{'id': 701}, {'id': 1802}] Played 4165363 3 \n",
"3025254 [{'id': 1801}] Played 4165363 3 \n",
"3025255 [{'id': 1802}] Played 4165363 3 \n",
"\n",
" seasonId dateutc winner venue wyId_x \\\n",
"3025251 10078 2018-06-28 18:00:00 16276 Mordovia Arena 2057995 \n",
"3025252 10078 2018-06-28 18:00:00 16276 Mordovia Arena 2057995 \n",
"3025253 10078 2018-06-28 18:00:00 16276 Mordovia Arena 2057995 \n",
"3025254 10078 2018-06-28 18:00:00 16276 Mordovia Arena 2057995 \n",
"3025255 10078 2018-06-28 18:00:00 16276 Mordovia Arena 2057995 \n",
"\n",
" label date \\\n",
"3025251 Panama - Tunisia, 1 - 2 2018-06-28 20:00:00-02:00 \n",
"3025252 Panama - Tunisia, 1 - 2 2018-06-28 20:00:00-02:00 \n",
"3025253 Panama - Tunisia, 1 - 2 2018-06-28 20:00:00-02:00 \n",
"3025254 Panama - Tunisia, 1 - 2 2018-06-28 20:00:00-02:00 \n",
"3025255 Panama - Tunisia, 1 - 2 2018-06-28 20:00:00-02:00 \n",
"\n",
" referees duration \\\n",
"3025251 [{'refereeId': 380581, 'role': 'referee'}, {'r... Regular \n",
"3025252 [{'refereeId': 380581, 'role': 'referee'}, {'r... Regular \n",
"3025253 [{'refereeId': 380581, 'role': 'referee'}, {'r... Regular \n",
"3025254 [{'refereeId': 380581, 'role': 'referee'}, {'r... Regular \n",
"3025255 [{'refereeId': 380581, 'role': 'referee'}, {'r... Regular \n",
"\n",
" competitionId wyId_y area_name weight firstName middleName \\\n",
"3025251 28 28 84 Harold Oshkaly \n",
"3025252 28 28 84 Harold Oshkaly \n",
"3025253 28 28 84 Harold Oshkaly \n",
"3025254 28 28 84 Harold Oshkaly \n",
"3025255 28 28 84 Harold Oshkaly \n",
"\n",
" lastName birthDate height wyId_x foot shortName \\\n",
"3025251 Cummings Segura 1992-03-01 180 116293 right H. Cummings \n",
"3025252 Cummings Segura 1992-03-01 180 116293 right H. Cummings \n",
"3025253 Cummings Segura 1992-03-01 180 116293 right H. Cummings \n",
"3025254 Cummings Segura 1992-03-01 180 116293 right H. Cummings \n",
"3025255 Cummings Segura 1992-03-01 180 116293 right H. Cummings \n",
"\n",
" passportArea_name role_name birthArea_name name wyId_y \n",
"3025251 Panama Defender Panama Panama 17929 \n",
"3025252 Panama Defender Panama Panama 17929 \n",
"3025253 Panama Defender Panama Panama 17929 \n",
"3025254 Panama Defender Panama Panama 17929 \n",
"3025255 Panama Defender Panama Panama 17929 "
]
},
"execution_count": 73,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# Display the last 5 rows of the raw DataFrame, df_wyscout_merge\n",
"df_wyscout_merge.tail()"
]
},
{
"cell_type": "code",
"execution_count": 74,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"(3025256, 41)\n"
]
}
],
"source": [
"# Print the shape of the raw DataFrame, df_wyscout_merge\n",
"print(df_wyscout_merge.shape)"
]
},
{
"cell_type": "code",
"execution_count": 75,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Index(['eventId', 'subEventName', 'playerId', 'positions', 'matchId',\n",
" 'eventName', 'teamId', 'matchPeriod', 'eventSec', 'subEventId', 'id',\n",
" 'tags', 'status', 'roundId', 'gameweek', 'seasonId', 'dateutc',\n",
" 'winner', 'venue', 'wyId_x', 'label', 'date', 'referees', 'duration',\n",
" 'competitionId', 'wyId_y', 'area_name', 'weight', 'firstName',\n",
" 'middleName', 'lastName', 'birthDate', 'height', 'wyId_x', 'foot',\n",
" 'shortName', 'passportArea_name', 'role_name', 'birthArea_name', 'name',\n",
" 'wyId_y'],\n",
" dtype='object')\n"
]
}
],
"source": [
"# Print the column names of the raw DataFrame, df_wyscout_merge\n",
"print(df_wyscout_merge.columns)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The joined dataset has forty features (columns). Full details of these attributes can be found in the [Data Dictionary](section3.3.1)."
]
},
{
"cell_type": "code",
"execution_count": 76,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"eventId int64\n",
"subEventName object\n",
"playerId int64\n",
"positions object\n",
"matchId int64\n",
"eventName object\n",
"teamId int64\n",
"matchPeriod object\n",
"eventSec float64\n",
"subEventId object\n",
"id int64\n",
"tags object\n",
"status object\n",
"roundId int64\n",
"gameweek int64\n",
"seasonId int64\n",
"dateutc object\n",
"winner int64\n",
"venue object\n",
"wyId_x int64\n",
"label object\n",
"date object\n",
"referees object\n",
"duration object\n",
"competitionId int64\n",
"wyId_y int64\n",
"area_name object\n",
"weight int64\n",
"firstName object\n",
"middleName object\n",
"lastName object\n",
"birthDate object\n",
"height int64\n",
"wyId_x int64\n",
"foot object\n",
"shortName object\n",
"passportArea_name object\n",
"role_name object\n",
"birthArea_name object\n",
"name object\n",
"wyId_y int64\n",
"dtype: object"
]
},
"execution_count": 76,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# Data types of the features of the raw DataFrame, df_wyscout_merge\n",
"df_wyscout_merge.dtypes"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Full details of these attributes and their data types can be found in the [Data Dictionary](section3.3.1)."
]
},
{
"cell_type": "code",
"execution_count": 77,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
"Int64Index: 3025256 entries, 0 to 3025255\n",
"Data columns (total 41 columns):\n",
" # Column Dtype \n",
"--- ------ ----- \n",
" 0 eventId int64 \n",
" 1 subEventName object \n",
" 2 playerId int64 \n",
" 3 positions object \n",
" 4 matchId int64 \n",
" 5 eventName object \n",
" 6 teamId int64 \n",
" 7 matchPeriod object \n",
" 8 eventSec float64\n",
" 9 subEventId object \n",
" 10 id int64 \n",
" 11 tags object \n",
" 12 status object \n",
" 13 roundId int64 \n",
" 14 gameweek int64 \n",
" 15 seasonId int64 \n",
" 16 dateutc object \n",
" 17 winner int64 \n",
" 18 venue object \n",
" 19 wyId_x int64 \n",
" 20 label object \n",
" 21 date object \n",
" 22 referees object \n",
" 23 duration object \n",
" 24 competitionId int64 \n",
" 25 wyId_y int64 \n",
" 26 area_name object \n",
" 27 weight int64 \n",
" 28 firstName object \n",
" 29 middleName object \n",
" 30 lastName object \n",
" 31 birthDate object \n",
" 32 height int64 \n",
" 33 wyId_x int64 \n",
" 34 foot object \n",
" 35 shortName object \n",
" 36 passportArea_name object \n",
" 37 role_name object \n",
" 38 birthArea_name object \n",
" 39 name object \n",
" 40 wyId_y int64 \n",
"dtypes: float64(1), int64(16), object(24)\n",
"memory usage: 969.4+ MB\n"
]
}
],
"source": [
"# Info for the raw DataFrame, df_wyscout_merge\n",
"df_wyscout_merge.info()"
]
},
{
"cell_type": "code",
"execution_count": 78,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" \n",
" eventId \n",
" playerId \n",
" matchId \n",
" teamId \n",
" eventSec \n",
" id \n",
" roundId \n",
" gameweek \n",
" seasonId \n",
" winner \n",
" wyId_x \n",
" competitionId \n",
" wyId_y \n",
" weight \n",
" height \n",
" wyId_x \n",
" wyId_y \n",
" \n",
" \n",
" \n",
" \n",
" count \n",
" 3.025256e+06 \n",
" 3.025256e+06 \n",
" 3.025256e+06 \n",
" 3.025256e+06 \n",
" 3.025256e+06 \n",
" 3.025256e+06 \n",
" 3.025256e+06 \n",
" 3.025256e+06 \n",
" 3.025256e+06 \n",
" 3.025256e+06 \n",
" 3.025256e+06 \n",
" 3.025256e+06 \n",
" 3.025256e+06 \n",
" 3.025256e+06 \n",
" 3.025256e+06 \n",
" 3.025256e+06 \n",
" 3.025256e+06 \n",
" \n",
" \n",
" mean \n",
" 5.694230e+00 \n",
" 8.953778e+04 \n",
" 2.494932e+06 \n",
" 3.004373e+03 \n",
" 1.390728e+03 \n",
" 2.158336e+08 \n",
" 4.391560e+06 \n",
" 1.815116e+01 \n",
" 1.709805e+05 \n",
" 2.317237e+03 \n",
" 2.494932e+06 \n",
" 4.797790e+02 \n",
" 4.797790e+02 \n",
" 7.622714e+01 \n",
" 1.820490e+02 \n",
" 8.953778e+04 \n",
" 3.004373e+03 \n",
" \n",
" \n",
" std \n",
" 3.141030e+00 \n",
" 1.169272e+05 \n",
" 1.591746e+05 \n",
" 2.925207e+03 \n",
" 8.347843e+02 \n",
" 3.023051e+07 \n",
" 5.686541e+04 \n",
" 1.126545e+01 \n",
" 4.054451e+04 \n",
" 3.021050e+03 \n",
" 1.591746e+05 \n",
" 1.845044e+02 \n",
" 1.845044e+02 \n",
" 7.149052e+00 \n",
" 7.032542e+00 \n",
" 1.169272e+05 \n",
" 2.925207e+03 \n",
" \n",
" \n",
" min \n",
" 1.000000e+00 \n",
" 1.200000e+01 \n",
" 1.694390e+06 \n",
" 6.740000e+02 \n",
" 0.000000e+00 \n",
" 8.817864e+07 \n",
" 4.165363e+06 \n",
" 0.000000e+00 \n",
" 9.291000e+03 \n",
" 0.000000e+00 \n",
" 1.694390e+06 \n",
" 2.800000e+01 \n",
" 2.800000e+01 \n",
" 0.000000e+00 \n",
" 0.000000e+00 \n",
" 1.200000e+01 \n",
" 6.740000e+02 \n",
" \n",
" \n",
" 25% \n",
" 1.000000e+00 \n",
" 9.380000e+03 \n",
" 2.500086e+06 \n",
" 1.619000e+03 \n",
" 6.608105e+02 \n",
" 1.988861e+08 \n",
" 4.405654e+06 \n",
" 8.000000e+00 \n",
" 1.811440e+05 \n",
" 6.740000e+02 \n",
" 2.500086e+06 \n",
" 3.640000e+02 \n",
" 3.640000e+02 \n",
" 7.200000e+01 \n",
" 1.780000e+02 \n",
" 9.380000e+03 \n",
" 1.619000e+03 \n",
" \n",
" \n",
" 50% \n",
" 8.000000e+00 \n",
" 2.562300e+04 \n",
" 2.516836e+06 \n",
" 2.460000e+03 \n",
" 1.374896e+03 \n",
" 2.191298e+08 \n",
" 4.405655e+06 \n",
" 1.800000e+01 \n",
" 1.811500e+05 \n",
" 1.633000e+03 \n",
" 2.516836e+06 \n",
" 4.260000e+02 \n",
" 4.260000e+02 \n",
" 7.600000e+01 \n",
" 1.820000e+02 \n",
" 2.562300e+04 \n",
" 2.460000e+03 \n",
" \n",
" \n",
" 75% \n",
" 8.000000e+00 \n",
" 1.345420e+05 \n",
" 2.565827e+06 \n",
" 3.766000e+03 \n",
" 2.109554e+03 \n",
" 2.352463e+08 \n",
" 4.406122e+06 \n",
" 2.800000e+01 \n",
" 1.811890e+05 \n",
" 3.173000e+03 \n",
" 2.565827e+06 \n",
" 5.240000e+02 \n",
" 5.240000e+02 \n",
" 8.100000e+01 \n",
" 1.870000e+02 \n",
" 1.345420e+05 \n",
" 3.766000e+03 \n",
" \n",
" \n",
" max \n",
" 1.000000e+01 \n",
" 5.685830e+05 \n",
" 2.576338e+06 \n",
" 1.983000e+04 \n",
" 3.537356e+03 \n",
" 2.802175e+08 \n",
" 4.406278e+06 \n",
" 3.800000e+01 \n",
" 1.812480e+05 \n",
" 1.983000e+04 \n",
" 2.576338e+06 \n",
" 7.950000e+02 \n",
" 7.950000e+02 \n",
" 1.010000e+02 \n",
" 2.030000e+02 \n",
" 5.685830e+05 \n",
" 1.983000e+04 \n",
" \n",
" \n",
"
\n",
"
"
],
"text/plain": [
" eventId playerId matchId teamId eventSec \\\n",
"count 3.025256e+06 3.025256e+06 3.025256e+06 3.025256e+06 3.025256e+06 \n",
"mean 5.694230e+00 8.953778e+04 2.494932e+06 3.004373e+03 1.390728e+03 \n",
"std 3.141030e+00 1.169272e+05 1.591746e+05 2.925207e+03 8.347843e+02 \n",
"min 1.000000e+00 1.200000e+01 1.694390e+06 6.740000e+02 0.000000e+00 \n",
"25% 1.000000e+00 9.380000e+03 2.500086e+06 1.619000e+03 6.608105e+02 \n",
"50% 8.000000e+00 2.562300e+04 2.516836e+06 2.460000e+03 1.374896e+03 \n",
"75% 8.000000e+00 1.345420e+05 2.565827e+06 3.766000e+03 2.109554e+03 \n",
"max 1.000000e+01 5.685830e+05 2.576338e+06 1.983000e+04 3.537356e+03 \n",
"\n",
" id roundId gameweek seasonId winner \\\n",
"count 3.025256e+06 3.025256e+06 3.025256e+06 3.025256e+06 3.025256e+06 \n",
"mean 2.158336e+08 4.391560e+06 1.815116e+01 1.709805e+05 2.317237e+03 \n",
"std 3.023051e+07 5.686541e+04 1.126545e+01 4.054451e+04 3.021050e+03 \n",
"min 8.817864e+07 4.165363e+06 0.000000e+00 9.291000e+03 0.000000e+00 \n",
"25% 1.988861e+08 4.405654e+06 8.000000e+00 1.811440e+05 6.740000e+02 \n",
"50% 2.191298e+08 4.405655e+06 1.800000e+01 1.811500e+05 1.633000e+03 \n",
"75% 2.352463e+08 4.406122e+06 2.800000e+01 1.811890e+05 3.173000e+03 \n",
"max 2.802175e+08 4.406278e+06 3.800000e+01 1.812480e+05 1.983000e+04 \n",
"\n",
" wyId_x competitionId wyId_y weight height \\\n",
"count 3.025256e+06 3.025256e+06 3.025256e+06 3.025256e+06 3.025256e+06 \n",
"mean 2.494932e+06 4.797790e+02 4.797790e+02 7.622714e+01 1.820490e+02 \n",
"std 1.591746e+05 1.845044e+02 1.845044e+02 7.149052e+00 7.032542e+00 \n",
"min 1.694390e+06 2.800000e+01 2.800000e+01 0.000000e+00 0.000000e+00 \n",
"25% 2.500086e+06 3.640000e+02 3.640000e+02 7.200000e+01 1.780000e+02 \n",
"50% 2.516836e+06 4.260000e+02 4.260000e+02 7.600000e+01 1.820000e+02 \n",
"75% 2.565827e+06 5.240000e+02 5.240000e+02 8.100000e+01 1.870000e+02 \n",
"max 2.576338e+06 7.950000e+02 7.950000e+02 1.010000e+02 2.030000e+02 \n",
"\n",
" wyId_x wyId_y \n",
"count 3.025256e+06 3.025256e+06 \n",
"mean 8.953778e+04 3.004373e+03 \n",
"std 1.169272e+05 2.925207e+03 \n",
"min 1.200000e+01 6.740000e+02 \n",
"25% 9.380000e+03 1.619000e+03 \n",
"50% 2.562300e+04 2.460000e+03 \n",
"75% 1.345420e+05 3.766000e+03 \n",
"max 5.685830e+05 1.983000e+04 "
]
},
"execution_count": 78,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# Description of the raw DataFrame, df_wyscout_merge, showing some summary statistics for each numberical column in the DataFrame\n",
"df_wyscout_merge.describe()"
]
},
{
"cell_type": "code",
"execution_count": 79,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
""
]
},
"execution_count": 79,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"image/png": "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SwghxODBg8Xp06eFn5+feOedd0RFRYVwcnISy5cvF127dhVvvPGGiIuLE3/7299EQUGB+OCDD0RsbKx49913jVoeAOKtt94SlZWVIiIiQrz11lvid7/7nbh9+7ZYs2aN+Oqrr8TIkSPFokWLRK9evUR6errIysoSfn5+Bj+ntrZW/OxnxnlMvq9Mffv2FZ07dxZvvvmmWL16tThw4ID45S9/KaqqqsTbb78txo8fL3+OUgeMUaY333xTCCFEcnKy2L17t/iP//gPUVJSIgoLC4Wtra3405/+JH75y1+KtLQ0IYQQkydPFi9evBBxcXHivffeM0o59JlS/a6trRXPnj0T+fn54t///d/FsWPHRJcuXURdXZ14+PCh+O1vfysePHggIiMjhaurq5gwYYLYv3+/yMnJET4+PsLc3NxoZdFnivdNCNO6d0KYVrtUW1srAgICRL9+/URERIT8eklJiaisrBQ2Njbya5aWlmLevHkiPj5ejBw5Unz44Yfi/fffN1pZ9L148ULs2bNHCCHE1q1bxaRJk8Svf/1rce/ePSGEECtXrhSbN28WixYtEra2tuLkyZNi4cKF4vTp06Jv377igw8+EOfOnRNXrlwRH3zwgVi5cqX4n//5n59crob3ztfXV9ja2ora2lrxt7/9TYwbN06MGTNGrFmzRtTV1YmYmBhhbW0twsLCjNY+6lPabyGEGD58uPif//kfERYWJv7+97+Lr776Sty7d0/8+c9/Fj//+c8FAPH73/9e/Od//qe4f/++0cuiePPNN8XLly9Fjx49xDvvvCPi4+PFf//3f4tPPvlEHD58WCQnJ4sxY8aIP/zhD2LatGnCzc1N7Nq1S7z55psiNjZW/hxjveOEePUzJ4QQWq1W3LlzRyxevFj893//t7h7964oKysTq1atErdu3RLt27cXQgij3z+lrRw6dKg4cuSICA8PFxkZGWL9+vViy5Ytora2VkRERIif/exnYtmyZeLFixdi48aN4syZM2L48OHil7/8pdHKUldXJ8sjhBBeXl4iJCRE7Nu3T0yZMkUcOnRI6HQ6MXjwYLFw4UJRUFAggoODRUVFhcjLyxOlpaXiV7/6ldHK05Tq6mrxX//1X6JXr15i2bJlIiMjQ8THx4vc3Fzx/vvvi3v37omnT5+qet8aXqeQkBBx+PBhcfz4cTFv3jxx/PhxERQU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L38pli9fLlda//znPxc1NTWqrNoVoun7tmDBAlFbWyuqqqpERESEWL9+vbh796549913xQcffCD+8Ic/qFIWRW1trXj8+LF4++23hRD11+n3v/+96Nevn7h9+7ZYv369iIyMFJ988omoqKgQf/jDH4xeJqUOTJw4URw/flz07t1bBAUFiXbt2on8/Hyxf/9+MWPGDLF//37xySefiMLCQvH111+Ltm3bCldXV1V2Wyg++ugj8dFHH4n4+HgRGBgorKyshLOzs/Dx8REzZ84U/v7+YvDgwSI4OFj1+6bsAujbt6+4c+eOSEhIEKGhoaJTp04iPz9ffP7552LWrFmisLBQfPzxx2Lv3r3im2++EX5+fqJ169ZyV9gHH3wgevXqZZTdBEII4ePjIxYtWiR69uwpAIiYmBjx17/+VcycOVO8//77YsCAAcLDw0MkJiYKIYS4deuW+Pvf/y58fHxEeHi40VahN8UU6rcQ391WtmvXTpSWloqJEyeKX/ziF6KgoEC88cYbYtu2baKoqEhkZmaq1k4K8f3XaN68eeJXv/qVmDRpkhCifpe70q6q6cWLF6K0tNSgPUb9cRri1q1bQoj65/PnP/+5+M1vfiNat24t3nzzTaO24ab6zCkePXokSktLZRv48ccfi+vXr4sRI0aI9evXi9zcXPHmm2+KKVOmiOzsbOHm5mbU3y/Ej79Gvr6+sr+khnfeeUdcuXJFABDvvPOO2LJlixg2bJgYNWqUmDBhgujatatYvny58PT0FAsWLBB9+vQRb7/9tpgyZYpq75SfOk5Rox/3U9tvY/eXlPL07t1beHh4iHfffVfY2tqKt956S/zlL38RcXFx4p133hETJ04UVlZWomPHjmLevHliyJAhqmRkEqJ+x+LChQtFnz59RKtWrcT/+3//T46HPDw8BAAxb948MXnyZJGcnCy8vb1lthiFMecqTLVdUp652tpa8d5774lNmzaJYcOGCQcHBzF37lzxzjvviNDQUPGzn/1MPHnyRFy+fFl88MEHcnefmu+57xs3RUZGivnz54vExETxi1/8QkydOlXVduCHzn21bdtW9OjRQ3Ts2FE8fvxY/O1vf5M7Io0991VbWytiYmLE8+fPhY+Pjxyb9+7dW9y/f19Mnz5dnD17VrRt21ZUV1eLdevWid/+9rciICDAaOVQ6D9zZmZm4r333hN/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TLEdMDW8Rj/O624bTPWZ0y/X6+6fmOo1evTokairq3vtk7H6TLEdMLUy7du3T4wYMUJ88cUXr21Hf0O7d+8WCxcuFKtWrWJf4DuY4jNnikxx7svU6nhBQYFYtmyZWLZsmRDCNOq4qbWVptoOEL1uDPL9CLdv3xZJSUni3LlzQgjBIF8Lo79rxhRWophqmV53ahf6cXjfWi7eu5bJ1O4bAHHq1CmRk5MjrK2tRWBgoPjrX//6uotF9E/N1NoBU8RrRESm2A6YWpkqKirEu++++7qLYUCZUDeVRT/Uspni3Jep1XFTK48QptdWElFjDPL9g5YtWybmzJkjXrx4IRwcHMThw4cZ5GuBTG0lihCmWSYiIiIiIiIi+tdlSsEGavlMce7L1Oq4qZWHiEwfg3z/IB8fH/Huu++KcePGievXr4vhw4czyNdCmeJKFFMsExERERERERERkTFw7ouIyLh4wM4/aNy4ccLV1VW89dZb4vr166+7OPQTmGKHwhTLREREREREREREZAyc+yIiMi4G+f5BHh4er7sIRERERERERERERERE9C+OQb5m4OXl9bqLIM2aNUsIIcSgQYNeazn0sUw/DMv0/UytPEKwTD8Uy/T9TK08QrBMPxTL9P1MrTxCsEw/FMv0/UytPEKwTD8Uy/TDmFqZTK08QrBMPxTL9P1MrTxCsEw/FMv0/UytPEKwTD+UKZZJUVBQ8LqLQD9BXl6eWLJkidixY4f4+c9//rqLY7LefN0FICIiIiIiIiIiIiIiIqJ/DIN8RERERERERERERERERC0Mg3xERERERERERERERERELQyDfEREREREREREREREREQtDIN8RERERERERERERERERC0Mg3xERERERERERERERERELQyDfEREREREREREREREREQtzM9edwFasrCwMBEWFva6i0FERERERERERERERET/YriTj4iIiIiIiIiIiIiIiKiFYZCPiIiIiIiIiIiIiIiIqIVhkI+IiIiIiIiIiIiIiIiohWGQj4iIiIiIiIiIiIiIiKiFYZCPiIiIiIiIiIiIiIiIqIVhkI+IiIiIiIiIiIiIiIiohWGQj4iIiIiIiIiIiIiIiKiFYZCPiIiIiIiIiIiIiIiIqIVhkI+IiIiIiIiIiIiIiIiohWGQj4iIiIiIiIiIiIiIiKiFYZCPiIiIiIiIiIiIiIiIqIVhkI+IiIiIiIiIiIiIiIiohWGQj4iIiIiIiIiIiIiIiKiFYZCPiIiIiIiIiIiIiIiIqIVhkI+IiIiIiIiIiIiIiIiohWGQj4iIiIiIiIiIiIiIiKiFYZCPiIiIiIiIiIiIiIiIqIVhkI+IiIiIiIiIiIiIiIiohWGQj4iIiIiIiIiIiIiIiKiFYZCPiIiIiIiIiIiIiIiIqIVhkI+IiIiIiIiIiIiIiIiohWGQj4iIiIiIiIiIiIiIiKiFYZCPiIiIiIiIiIiIiIiIqIVhkI+IiIiIiIiIiIiIiIiohWGQj4iIiIiIiIiIiIiIiKiFYZCPiIiIiIiIiIiIiIiIqIVhkI+IiIiIiIiIiIiIiIiohWGQj4iIiIiIiIiIiIiIiKiFYZCPiIiIiIiIiIiIiIiIqIVhkI+IiIiIiIiIiIiIiIiohWGQj4iIiIiIiIiIiIiIiKiFYZCPiIiIiIiIiIiIiIiIqIVhkI+IiIiIiIiIiIiIiIiohWGQj4iIiIiIiIiIiIiIiKiFYZCPiIiIiIiIiIiIiIiIqIVhkI+IiIiIiIiIiIiIiIiohWGQj4iIiIiIiIiIiIiIiKiFYZCPiIiIiIiIiIiIiIiIqIVhkI+IiIiIiIiIiIiIiIiohWGQj4iIiIiIiIiIiIiIiKiFYZCPiIiIiIiIiIiIiIiIqIVhkI+IiIiIiIiIiIiIiIiohWGQj4iIiIiIiIiIiIiIiKiFYZCPiIiIiIiIiIiIiIiIqIVhkI+IiIiIiIiIiIiIiIiohWGQj4iIiIiIiIiIiIiIiKiFYZCPiIiIiIiIiIiIiIiIqIVhkI+IiIiIiIiIiIiIiIiohWGQj4iIiIiIiIiIiIiIiKiFYZCPiIiIiIiIiIiIiIiIqIVhkI+IiIiIiIiIiIiIiIiohWGQj4iIiIiIiIiIiIiIiKiFYZCPiIiIiIiIiIiIiIiIqIVhkI+IiIiIiIiIiIiIiIiohWGQj4iIiIiIiIiIiIiIiKiFYZCPiIiIiIiIiIiIiIiIqIVhkI+IiIiIiIiIiIiIiIiohWGQj4iIiIiIiIiIiIiIiKiFYZCPiIiIiIiIiIiIiIiIqIVhkI+IiIiIiIiIiIiIiIiohWGQj4iIiIiIiIiIiIiIiKiFYZCPiIiIiIiIiIiIiIiIqIVhkI+IiIiIiIiIiIiIiIiohWGQj4iIiIiIiIiIiIiIiKiFYZCPiIiIiIiIiIiIiIiIqIVhkI+IiIiIiIiIiIiIiIiohWGQj4iIiIiIiIiIiIiIiKiFYZCPiIiIiIiIiIiIiIiIqIVhkI+IiIiIiIiIiIiIiIiohWGQj4iIiIiIiIiIiIiIiKiFYZCPiIiIiIiIiIiIiIiIqIVhkI+IiIiIiIiIiIiIiIiohWGQj4iIiIiIiIiIiIiIiKiFYZCPiIiIiIiIiIiIiIiIqIVhkI+IiIiIiIiIiIiIiIiohWGQj4iIiIiIiIiIiIiIiKiFYZCPiIiIiIiIiIiIiIiIqIVhkI+IiIiIiIiIiIiIiIiohWGQj4iIiIiIiIiIiIiIiKiFYZCPiIiIiIiIiIiIiIiIqIVhkI+IiIiIiIiIiIiIiIiohWGQj4iIiIiIiIiIiIiIiKiFYZCPiIiIiIiIiIiIiIiIqIVhkI+IiIiIiIiIiIiIiIiohWGQj4iIiIiIiIiIiIiIiKiFYZCPiIiIiIiIiIiIiIiIqIVhkI+IiIiIiIiIiIiIiIiohWGQj4iIiIiIiIiIiIiIiKiFYZCPiIiIiIiIiIiIiIiIqIVhkI+IiIiIiIiIiIiIiIiohWGQj4iIiIiIiIiIiIiIiKiFYZCPiIiIiIiIiIiIiIiIqIVhkI+IiIiIiIiIiIiIiIiohWGQj4iIiIiIiIiIiIiIiKiFYZCPiIiIiIiIiIiIiIiIqIVhkI+IiIiIiIiIiIiIiIiohWGQj4iIiIiIiIiIiIiIiKiFYZCPiIiIiIiIiIiIiIiIqIVhkI+IiIiIiIiIiIiIiIiohWGQj4iIiIiIiIiIiIiIiKiFYZCPiIiIiIiIiIiIiIiIqIVhkI+IiIiIiIiIiIiIiIiohWGQj4iIiIiIiIiIiIiIiKiFYZCPiIiIiIiIiIiIiIiIqIVhkI+IiIiIiIiIiIiIiIiohWGQj4iIiIiIiIiIiIiIiKiFYZCPiIiIiIiIiIiIiIiIqIVhkI+IiIiIiIiIiIiIiIiohWGQj4iIiIiIiIiIiIiIiKiFYZCPiIiIiIiIiIiIiIiIqIVhkI+IiIiIiIiIiIiIiIiohWGQj4iIiIiIiIiIiIiIiKiFYZCPiIiIiIiIiIiIiIiIqIVhkI+IiIiIiIiIiIiIiIiohWGQj4iIiIiIiIiIiIiIiKiFYZCPiIiIiIiIiIiIiIiIqIVhkI+IiIiIiIiIiIiIiIiohWGQj4iIiIiIiIiIiIiIiKiFYZCPiIiIiIiIiIiIiIiIqIVhkI+IiIiIiIiIiIiIiIiohWGQj4iIiIiIiIiIiIiIiKiFYZCPiIiIiIiIiIiIiIiIqIVhkI+IiIiIiIiIiIiIiIiohWGQj4iIiIiIiIiIiIiIiKiFYZCPiIiIiIiIiIiIiIiIqIVhkI+IiIiIiIiIiIiIiIiohWGQj4iIiIiIiIiIiIiIiKiFYZCPiIiIiIiIiIiIiIiIqIVhkI+IiIiIiIiIiIiIiIiohWGQj4iIiIiIiIiIiIiIiKiFYZCPiIiIiIiIiIiIiIiIqIVhkI+IiIiIiIiIiIiIiIiohWGQj4iIiIiIiIiIiIiIiKiFYZCPiIiIiIiIiIiIiIiIqIVhkI+IiIiIiIiIiIiIiIiohWGQj4iIiIiIiIiIiIiIiKiFYZCPiIiIiIiIiIiIiIiIqIVhkI+IiIiIiIiIiIiIiIiohWGQj4iIiIiIiIiIiIiIiKiFYZCPiIiIiIiIiIiIiIiIqIVhkI+IiIiIiIiIiIiIiIiohWGQj4iIiIiIiIiIiIiIiKiFYZCPiIiIiIiIiIiIiIiIqIVhkI/+//buPUjLsvD/+AdBQJRFGozJxVHEwFEHEgvPBBiMkGSWiXggNE0MwwOOlZsWVpMzGmuwqyVk4AqNSjPkkcnDQh7IsyklkKFCouQAYzgoy2F/fzg+084uSh6+dP3m9fprn+u+7+u59rn/fM913wAAAAAAABRG5AMAAAAAAIDCiHwAAAAAAABQGJEPAAAAAAAACiPyAQAAAAAAQGFEPgAAAAAAACiMyAcAAAAAAACFEfkAAAAAAACgMCIfAAAAAAAAFEbkAwAAAAAAgMKIfAAAAAAAAFAYkQ8AAAAAAAAKI/IBAAAAAABAYUQ+AAAAAAAAKIzIBwAAAAAAAIUR+QAAAAAAAKAwIh8AAAAAAAAURuQDAAAAAACAwoh8AAAAAAAAUBiRDwAAAAAAAAoj8gEAAAAAAEBhRD4AAAAAAAAojMgHAAAAAAAAhRH5AAAAAAAAoDAiHwAAAAAAABRG5AMAAAAAAIDCiHwAAAAAAABQGJEPAAAAAAAACiPyAQAAAAAAQGFEPgAAAAAAACiMyAcAAAAAAACFEfkAAAAAAACgMCIfAAAAAAAAFEbkAwAAAAAAgMKIfAAAAAAAAFAYkQ8AAAAAAAAKI/IBAAAAAABAYUQ+AAAAAAAAKIzIBwAAAAAAAIUR+QAAAAAAAKAwIh8AAAAAAAAURuQDAAAAAACAwoh8AAAAAAAAUBiRDwAAAAAAAAoj8gEAAAAAAEBhRD4AAAAAAAAojMgHAAAAAAAAhRH5AAAAAAAAoDAiHwAAAAAAABRG5AMAAAAAAIDCiHwAAAAAAABQGJEPAAAAAAAACiPyAQAAAAAAQGFEPgAAAAAAACiMyAcAAAAAAACFEfkAAAAAAACgMCIfAAAAAAAAFEbkAwAAAAAAgMKIfAAAAAAAAFAYkQ8AAAAAAAAKI/IBAAAAAABAYUQ+AAAAAAAAKIzIBwAAAAAAAIUR+QAAAAAAAKAwIh8AAAAAAAAURuQDAAAAAACAwoh8AAAAAAAAUBiRDwAAAAAAAAoj8gEAAAAAAEBhRD4AAAAAAAAojMgHAAAAAAAAhRH5AAAAAAAAoDAiHwAAAAAAABRG5AMAAAAAAIDCiHwAAAAAAABQGJEPAAAAAAAACiPyAQAAAAAAQGFEPgAAAAAAACiMyAcAAAAAAACFEfkAAAAAAACgMCIfAAAAAAAAFEbkAwAAAAAAgMKIfAAAAAAAAFAYkQ8AAAAAAAAKI/IBAAAAAABAYUQ+AAAAAAAAKIzIBwAAAAAAAIUR+QAAAAAAAKAwIh8AAAAAAAAURuQDAAAAAACAwoh8AAAAAAAAUBiRDwAAAAAAAAoj8gEAAAAAAEBhRD4AAAAAAAAojMgHAAAAAAAAhRH5AAAAAAAAoDAiHwAAAAAAABRG5AMAAAAAAIDCiHwAAAAAAABQGJEPAAAAAAAACiPyAQAAAAAAQGFEPgAAAAAAACiMyAcAAAAAAACFEfkAAAAAAACgMCIfAAAAAAAAFEbkAwAAAAAAgMKIfAAAAAAAAFAYkQ8AAAAAAAAKI/IBAAAAAABAYUQ+AAAAAAAAKIzIBwAAAAAAAIUR+QAAAAAAAKAwIh8AAAAAAAAURuQDAAAAAACAwoh8AAAAAAAAUBiRDwAAAAAAAAoj8gEAAAAAAEBhRD4AAAAAAAAojMgHAAAAAAAAhRH5AAAAAAAAoDAiHwAAAAAAABRG5AMAAAAAAIDCiHwAAAAAAABQGJEPAAAAAAAACiPyAQAAAAAAQGFEPgAAAAAAACiMyAcAAAAAAACFEfkAAAAAAACgMCIfAAAAAAAAFEbkAwAAAAAAgMKIfAAAAAAAAFAYkQ8AAAAAAAAKI/IBAAAAAABAYUQ+AAAAAAAAKIzIBwAAAAAAAIUR+QAAAAAAAKAwIh8AAAAAAAAURuQDAAAAAACAwoh8AAAAAAAAUBiRDwAAAAAAAAoj8gEAAAAAAEBhRD4AAAAAAAAojMgHAAAAAAAAhRH5AAAAAAAAoDAiHwAAAAAAABRG5AMAAAAAAIDCiHwAAAAAAABQGJEPAAAAAAAACiPyAQAAAAAAQGFEPgAAAAAAACiMyAcAAAAAAACFEfkAAAAAAACgMCIfAAAAAAAAFEbkAwAAAAAAgMKIfAAAAAAAAFAYkQ8AAAAAAAAKI/IBAAAAAABAYUQ+AAAAAAAAKIzIBwAAAAAAAIUR+QAAAAAAAKAwIh8AAAAAAAAURuQDAAAAAACAwoh8AAAAAAAAUBiRDwAAAAAAAAoj8gEAAAAAAEBhRD4AAAAAAAAojMgHAAAAAAAAhRH5AAAAAAAAoDAiHwAAAAAAABRG5AMAAAAAAIDCiHwAAAAAAABQGJEPAAAAAAAACiPyAQAAAAAAQGFEPgAAAAAAACiMyAcAAAAAAACFEfkAAAAAAACgMCIfAAAAAAAAFEbkAwAAAAAAgMKIfAAAAAAAAFAYkQ8AAAAAAAAKI/IBAAAAAABAYUQ+AAAAAAAAKIzIBwAAAAAAAIUR+QAAAAAAAKAwIh8AAAAAAAAURuQDAAAAAACAwoh8AAAAAAAAUBiRDwAAAAAAAAoj8gEAAAAAAEBhRD4AAAAAAAAojMgHAAAAAAAAhRH5AAAAAAAAoDAiHwAAAAAAABRG5AMAAAAAAIDCiHwAAAAAAABQGJEPAAAAAAAACiPyAQAAAAAAQGFEPgAAAAAAACiMyAcAAAAAAACFEfkAAAAAAACgMCIfAAAAAAAAFEbkAwAAAAAAgMKIfAAAAAAAAFAYkQ8AAAAAAAAKI/IBAAAAAABAYUQ+AAAAAAAAKIzIBwAAAAAAAIUR+QAAAAAAAKAwIh8AAAAAAAAURuQDAAAAAACAwoh8AAAAAAAAUBiRDwAAAAAAAAoj8gEAAAAAAEBhRD4AAAAAAAAojMgHAAAAAAAAhRH5AAAAAAAAoDAiHwAAAAAAABRG5AMAAAAAAIDCiHwAAAAAAABQGJEPAAAAAAAACiPyAQAAAAAAQGFEPgAAAAAAAChMhx09cf369amvr8/ChQvzr3/9K7169crXvva1jB8/Ph06tJxm/vz5mTVrVl5++eVUVVVl5MiRmTRpUnbfffcW5zU1NeWmm27KHXfckVWrVqVjx47p379/JkyYkMMPP7zFua+88kpGjBix3fU999xz6dSpU+XzPffck5tvvjnLli3L1q1bs//++2fs2LEZM2ZMq2sHDx6cNWvWtDnvjBkzMnjw4MrnTZs2ZcaMGbnzzjuzevXq9OzZM8OGDcsFF1yQqqqq7f+AAAAAAAAAH0JNTU1WrlyZhoaGFuOvvPJKRo8enaeffrpVq+F/18d1P3fojr/11ls57bTTsmLFigwdOjTDhw/P008/nWuuuSZPPvlkbrjhhrRr1y5J8utf/zpTp05Nv379csYZZ2T58uWZNWtW/vKXv+Tmm29Ox44dkyTbtm3L+eefn4cffjh9+/bN2LFjs2HDhixYsCDjx4/P1KlTM3LkyMoali1bliQZNWpU9t9//1ZrbN++feXvG264Idddd1169OiR0aNHp0OHDmlsbMyVV16Zv//97/nhD39YOffNN9/MmjVrMmDAgBx77LGt5t13330rf2/evDnnnHNOHn/88QwaNCjHHXdcnn/++cyePTvPPvtsbrnllsr/BwAAAAAA8FEtXrw48+bNy6BBg1qMv/baaznvvPOyadOmnbQyPoyP837uUOS78cYbs2LFitTU1GTcuHGV8cmTJ+euu+7KokWLMmTIkKxevTrTpk3LoYcemoaGhuy6665Jkl/+8pe5/vrrc9ttt+WMM85Iktx77715+OGHM2LEiNTW1laK5DnnnJOTTz45V111VY477rhKNHsv8p133nk58MADt7vW1157LfX19enVq1fmzZuX7t27V9Z6+umnp6GhISeddFIOPvjgJMnSpUuTJCeccEKL/60tN998cx5//PF861vfymWXXVYZv+qqqzJnzpzcc889+epXv7ojPykAAAAAAMD72rhxY6644ooMHDiwxfj999+fK664InvttddOWhkfxsd9P3fonXyvvvpqPvOZz+S0005rMT5q1KgkyTPPPJMkufXWW7Nly5acd955lcCXJBMmTMgee+yR22+/vTL2xz/+MUny3e9+t8WWwz59+mTUqFFZt25dnn/++cr4smXLsuuuu6ZPnz7vu9YHH3wwmzdvzllnnVUJfEmy++6756yzzkqS/OlPf2oxb5L069fvA3+HOXPmpLq6OhdffHGL8bPPPjsnnXRSi8eFAgAAAAAAfBS1tbUZNGhQq11fDz30UC6++OLU1NTspJV9cpqamvLUU08lSWbPnp2mpqadvKKPz8d9P3doJ98vfvGLNsdXrFiRJOnRo0eS5IknnkiSfOELX2hxXqdOnfK5z30uDz/8cDZs2JCuXbtm5MiR6d27d3r37t1q3vd2723cuLEytmzZsvTu3btFPGzLIYcckgsvvDBHHnnkDs+bfHDke/HFF/Pqq6/mzDPPbLWGXr165eqrr37f6wEAAAAAAHbUM888kwULFuSuu+7KTTfd1OLYlClTkiSPPfbYzljaJ6apqSknn3xyNmzYkOTdzVd33HFH5s2bV/zr0j6J+7lDO/n+U3Nzc9auXZs5c+Zk+vTp2XvvvfOVr3wlSbJy5cr06NEje+yxR6vrqqurkyQvvfRSkuT444/PRRdd1CqYNTU1ZdGiRUmSAw44IMm7UW7VqlX51Kc+lSlTpmTYsGHp379/TjrppNxxxx0trh8wYEC+853vtLnj7/77728xb/Ju5Ntzzz0zb968fPnLX07//v1z3HHHZdq0aS3q8PLly5Mkn/3sZ7No0aKceuqpGTBgQI455phcffXVLcIhAAAAAADAh9XU1JSamppcfvnl6dat285ezv+ZOXPmVALfezZs2JA5c+bspBV9PD6p+9muubm5+b+54LrrrssNN9yQ5N0dfA0NDdl///2TvLuLrlevXlmwYEGr66655prMnDkzv/3tb3PUUUdtd/66urpMnz49gwcPzowZM5Ikzz77bMaMGZPk3R13Rx99dNavX58HH3wwb775ZiZOnJhJkya977r//Oc/Z/z48enevXseeOCBdOnSJdu2bcvAgQPz9ttvZ6+99srw4cPTrl27PPLII3n55Zdz5JFHZubMmenQoUNmzZqVn//85xk6dGgaGxvzxS9+Mb17987jjz+ev/3tbznssMMye/bsD9xpCAAAAAAA8H5qa2uzfPnySo+pra3N008/nYaGhhbnPfbYYxk3blz++te/tng1WqkuueSSyivi/tPAgQO3+9TJEnxS9/O/vuPV1dU5++yzs2rVqjzwwAM5/fTTM3PmzBx88MHZsmXLdrdLvje+adOm7c49f/781NXVpWvXrrnyyisr4xs2bEjv3r1z9NFHp6amJrvs8u4GxDVr1mTs2LG5/vrrM2LEiBx44IFtzrt06dJMmjQpzc3NmTJlSrp06ZIkWbduXfbdd99UVVWlvr4+VVVVlTVeeOGFaWxszNy5czNu3Li8/fbbSZLGxsb85Cc/ySmnnJIk2bp1ay655JIsWLAgc+fOzTe/+c3/5ucEAAAAAABo4c4778wbb7yRQw89NEmyefPmbN26NYceemibEez/F1OnTt3ZS/hEfFL387+OfN/4xjcqfy9cuDATJkzI9773vdx5553p3LlzNm/e3OZ17z36crfddmvz+G233ZYf/ehH6dixY+rq6rLPPvtUjh177LFt7g7s2bNnJk6cmMsvvzx33313m5Hvueeey7nnnps333wzkydPzogRIyrHevTokT/84Q+trunUqVNqamrS2NiYu+++O+PGjauExYMOOqgS+JKkffv2ueyyy7JgwYLce++9Ih8AAAAAAPCRNDQ0ZMuWLZXPs2bNypIlS3LttdfuxFXxYX1S9/Mj7d0cMmRIjjzyyDz66KNZuXJlqqqqWj0r9T3vjXft2rXVsenTp6euri5dunRJfX19jjjiiB1ew8EHH5wk+ec//9nq2MKFC3PRRRfl7bffzuTJk/Ptb397h+fdZ5990q1bt8q8771n8KCDDmp1bnV1daqqqrJq1aodnh8AAAAAAKAt1dXVLT5XVVWlc+fO2XfffXfSivgoPqn7ucsHnbBly5Y8+uijeeSRR9o8vvfeeydJ1q9fn/322y9r167NO++80+q8V199NbvsskuLBTc3N+fKK69MXV1d9txzz8yaNavN9/WtXLkyixcvrjwy8z+9912dOnVqMT5//vxMnDgxmzZtypQpU9oMfGvXrs2TTz6Z1157rdWx5ubmbNq0qTLvfvvtlyTb3am4ZcuWdO7cuc1jAAAAAAAA8HH6wMiXJBMmTMill16arVu3tjq2dOnStGvXLr169cphhx2Wbdu25cknn2xxzqZNm/Lss8/mgAMOqOyIS5Krr746t956a3r27Jk5c+ZkwIABbX5/XV1dxo8fn4ceeqjVsaeeeipJcsghh1TG7rvvvvzgBz9Iu3btUltbm1NPPbXNeRsbG3P66afnN7/5TatjS5YsyTvvvFOZt3///unYsWOeeOKJVr/DP/7xj2zcuDH9+vVr83sAAAAAAAA+rIsvvjgNDQ2txg8//PAsW7YsHTp8pAc38n/s47qfHxj5OnTokOHDh2fdunWtYtjcuXOzZMmSDBkyJD169Mjo0aPTvn371NXVVd7BlyS/+tWv8tZbb2XMmDGVsQceeCCzZs3KnnvumVtuuSUHHHDAdtdw/PHHJ0nq6+uzcePGyviKFSty4403plu3bjnhhBOSJK+//nq+//3vp7m5ObW1tZVr2zJ06NB07tw5v//977NixYrK+FtvvZWf/exnSZLTTjstybuPGR05cmRWr16dG2+8sXLu5s2bc8011yRJvv71r2/3uwAAAAAAAODj0q65ubn5g05as2ZNTjnllLz++us55phj0rdv37zwwgtZvHhxevXqlblz56Znz55JkmuvvTYzZsxInz59MnTo0Lz44otZuHBhBg4cmNmzZ6djx45JktGjR2f58uU54ogj8vnPf77N7x01alT69OmTJJk8eXLuuuuuVFdXZ9iwYfn3v/+d++67L01NTZk+fXqGDRuWJPnpT3+ahoaG7LPPPjnxxBPbnHfAgAEZPHhwkuR3v/tdfvzjH6dLly4ZNWpUOnbsmIULF2b16tU599xzc+mll1auW7t2bcaOHZtXXnklRx11VA488MAsXrw4L7zwQkaNGpXa2tod/d0BAAAAAADgQ9uhyJckb7zxRqZNm5bGxsasX78+n/70pzN8+PCcf/756d69e+W85ubmzJ07N3Pnzs3KlSuz1157Zfjw4bngggvStWvXJMmGDRu2G/b+U319fb70pS8lSbZt25Zbbrklt99+e1566aXstttuGThwYCZOnJj+/ftXrjnxxBOzdOnS95133LhxqampqXxetGhRZs6cmSVLlqS5uTl9+/bNmWeemdGjR7e6dv369amvr899992XdevWpbq6OieffHLOOuustG/f/gP/JwAAAAAAAPiodjjyAQAAAAAAAP8bPvCdfAAAAAAAAMD/FpEPAAAAAAAACiPyAQAAAAAAQGFEPgAAAAAAACiMyAcAAAAAAACFEfkAAAAAAACgMCIfAAAAAAAAFEbkAwAAAAAAgMKIfAAAAAAAAFCY/wen3YVwt5h8gQAAAABJRU5ErkJggg==\n",
"text/plain": [
""
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"# Plot visualisation of the missing values for each feature of the raw DataFrame, df_wyscout_merge\n",
"msno.matrix(df_wyscout_merge, figsize = (30, 7))"
]
},
{
"cell_type": "code",
"execution_count": 80,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"Series([], dtype: int64)"
]
},
"execution_count": 80,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# Counts of missing values\n",
"null_value_stats = df_wyscout_merge.isnull().sum(axis=0)\n",
"null_value_stats[null_value_stats != 0]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The visualisation shows us that there are no missing values in the DataFrame."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"---\n",
"\n",
"## 4. Data Engineering \n",
"Before any Feature Engineering or Data Visualisation, we first need to clean and wrangle the datasets to a form that meet our needs."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 4.1. Sort DataFrame \n",
"Sort data by `matchId`, `matchPeriod`, and `eventSec`. Important for when determining previous events. which are attributes created for the DataFrame in the Data Engineering notebook."
]
},
{
"cell_type": "code",
"execution_count": 81,
"metadata": {},
"outputs": [],
"source": [
"# Sort data by matchId, matchPeriod, and eventSec\n",
"df_wyscout_merge = df_wyscout_merge.sort_values(['matchId', 'matchPeriod', 'eventSec'])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"---\n",
"\n",
"## 5. Export Data \n",
"Export Data ready for data engineering in the subsequent notebooks."
]
},
{
"cell_type": "code",
"execution_count": 82,
"metadata": {},
"outputs": [],
"source": [
"# Export Shots DataFrame as CSV\n",
"if not os.path.exists(os.path.join(data_dir_wyscout, 'raw', 'csv', 'combined', 'wyscout_big5_combined.csv')):\n",
" df_wyscout_merge.to_csv(os.path.join(data_dir_wyscout, 'raw', 'csv', 'combined', 'wyscout_big5_combined.csv'), index=None, header=True)\n",
"else:\n",
" pass"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"---\n",
"\n",
"## 6. Summary \n",
"This notebook parses Wyscout data using [pandas](http://pandas.pydata.org/) for data manipulation through DataFrames."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"---\n",
"\n",
"## 7. Next Steps \n",
"The step is to take the parsed dataset created in this notebook and engineer the data for new features, which is carrired out in the follow [Data Engineering](https://nbviewer.jupyter.org/github/eddwebster/football_analytics/blob/master/notebooks/3_data_engineering/Wyscout%20Data%20Engineering.ipynb) notebook. This data is then ready for use in projects including Expected Goals (xG) models and Tableau visualisations."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"---\n",
"\n",
"## 8. References \n",
"* Data Engineering notebook: https://nbviewer.jupyter.org/github/eddwebster/football_analytics/blob/master/notebooks/3_data_engineering/Wyscout%20Data%20Engineering.ipynb\n",
"* Wyscout: https://wyscout.com/\n",
"* Wyscout Events data manual: https://footballdata.wyscout.com/events-manual/\n",
"* Pappalardo, Luca; Massucco, Emanuele (2019): Soccer match event dataset. figshare. Collection. https://doi.org/10.6084/m9.figshare.c.4415000.v5\n",
"* Pappalardo, L., Cintia, P., Rossi, A. et al. **A public data set of spatio-temporal match events in soccer competitions**. Scientific Data 6, 236 (2019) doi:10.1038/s41597-019-0247-7, https://www.nature.com/articles/s41597-019-0247-7\n",
"* Custom function to flatten pandas DataFrames with nested JSON column: https://stackoverflow.com/questions/39899005/how-to-flatten-a-pandas-dataframe-with-some-columns-as-json\n",
"* WyIDs: https://support.wyscout.com/matches-wyid-events"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"---\n",
"\n",
"## 9. Further Reading "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"---\n",
"\n",
"***Visit my website [EddWebster.com](https://www.eddwebster.com) or my [GitHub Repository](https://github.com/eddwebster) for more projects. If you'd like to get in contact, my Twitter handle is [@eddwebster](http://www.twitter.com/eddwebster) and my email is: edd.j.webster@gmail.com.***"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"[Back to the top](#top)"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.6"
},
"varInspector": {
"cols": {
"lenName": 16,
"lenType": 16,
"lenVar": 40
},
"kernels_config": {
"python": {
"delete_cmd_postfix": "",
"delete_cmd_prefix": "del ",
"library": "var_list.py",
"varRefreshCmd": "print(var_dic_list())"
},
"r": {
"delete_cmd_postfix": ") ",
"delete_cmd_prefix": "rm(",
"library": "var_list.r",
"varRefreshCmd": "cat(var_dic_list()) "
}
},
"oldHeight": 642,
"position": {
"height": "664px",
"left": "1059px",
"right": "20px",
"top": "-2px",
"width": "489px"
},
"types_to_exclude": [
"module",
"function",
"builtin_function_or_method",
"instance",
"_Feature"
],
"varInspector_section_display": "block",
"window_display": false
}
},
"nbformat": 4,
"nbformat_minor": 4
}