{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Opta Data Engineering\n", "##### Notebook to engineer [Opta data](https://www.statsperform.com/opta/) by [Stats Perform](https://www.statsperform.com/) Event data using [pandas](http://pandas.pydata.org/).\n", "\n", "### By [Edd Webster](https://www.twitter.com/eddwebster)\n", "Notebook first written: 20/01/2022
\n", "Notebook last updated: 01/02/2022\n", "\n", "![Opta](../../img/logos/opta_sports_logo_small.png)\n", "\n", "![Stats Perform](../../img/logos/stats_perform_logo_small.png)\n", "\n", "![Watford F.C.](../../img/club_badges/premier_league/watford_fc_logo_small.png)\n", "\n", "Click [here](#section4) to jump straight into the Data Engineering section and skip the [Notebook Brief](#section2) and [Data Sources](#section3) sections." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "___\n", "\n", "\n", "## Introduction\n", "This notebook engineers a parsed F24 and F7 [Opta data](https://www.statsperform.com/opta/) by [Stats Perform](https://www.statsperform.com/) that have been provided by [Watford F.C](https://www.watfordfc.com/), using [pandas](http://pandas.pydata.org/) for data manipulation through DataFrames.\n", "\n", "For more information about this notebook and the author, I am 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/); and\n", "* [public.tableau.com/profile/edd.webster](https://public.tableau.com/profile/edd.webster).\n", "\n", "A static version of this notebook can be found [here](https://nbviewer.org/github/eddwebster/watford/blob/main/notebooks/2_data_engineering/Opta%20Data%20Engineering.ipynb). This notebook has an accompanying [`watford`](https://github.com/eddwebster/watford) GitHub repository and for my full repository of football analysis, see my [`football_analysis`](https://github.com/eddwebster/football_analytics) GitHub repository." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "___\n", "\n", "## Notebook Contents\n", "1. [Notebook Dependencies](#section1)
\n", "2. [Notebook Brief](#section2)
\n", "3. [Data Sources](#section3)
\n", " 1. [Introduction](#section3.1)
\n", " 2. [Read in the Datasets](#section3.2)
\n", " 3. [Initial Data Handling](#section3.3)
\n", "4. [Data Engineering](#section4)
\n", " 1. [Assign Raw DataFrame to Engineered DataFrame](#section4.1)
\n", " 2. [Rename Columns](#section4.2)
\n", " 3. [Drop Duplicate Columns](#section4.3)
\n", " 4. [Sort the DataFrame](#section4.4)
\n", " 3. [Determine Each Player's Most Frequent Position](#section4.3)
\n", " 6. [Determine Each Player's Total Minutes Played](#section4.6)
\n", " 7. [Break Down All location Attributes](#section4.7)
\n", "5. [Summary](#section5)
\n", "6. [Next Steps](#section6)
\n", "7. [References](#section7)
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "___\n", "\n", "\n", "\n", "## 1. Notebook Dependencies\n", "\n", "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; and\n", "* [`pandas`](http://pandas.pydata.org/) for data analysis and manipulation.\n", "\n", "All packages used for this notebook 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": 1, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Setup Complete\n" ] } ], "source": [ "# 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", "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 pandas_profiling as pp\n", "import os\n", "import re\n", "import chardet\n", "import random\n", "from io import BytesIO\n", "from pathlib import Path\n", "\n", "# Reading Directories\n", "import glob\n", "import os\n", "\n", "# Working with JSON\n", "import json\n", "from pandas import json_normalize\n", "\n", "# Data Visualisation\n", "import matplotlib as mpl\n", "import matplotlib.pyplot as plt\n", "import seaborn as sns\n", "import missingno as msno\n", "\n", "# Requests and downloads\n", "import tqdm\n", "import requests\n", "\n", "# Machine Learning\n", "import scipy as sp\n", "import scipy.spatial\n", "from scipy.spatial import distance\n", "from sklearn.ensemble import RandomForestClassifier\n", "import sklearn.metrics as sk_metrics\n", "from sklearn.metrics import log_loss, brier_score_loss, roc_auc_score , roc_curve, average_precision_score\n", "from sklearn.model_selection import train_test_split, KFold, cross_val_score, GridSearchCV, RandomizedSearchCV\n", "from sklearn.linear_model import LogisticRegression\n", "from scikitplot.metrics import plot_roc_curve, plot_precision_recall_curve, plot_calibration_curve\n", "import pickle\n", "from xgboost import XGBClassifier\n", "\n", "# Display in Jupyter\n", "from IPython.display import Image, 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 message\n", "print(\"Setup Complete\")" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "scrolled": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Python: 3.7.6\n", "NumPy: 1.19.1\n", "pandas: 1.1.3\n", "matplotlib: 3.3.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__))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Defined Filepaths" ] }, { "cell_type": "code", "execution_count": 3, "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_second_spectrum = os.path.join(base_dir, 'data', 'second_spectrum')\n", "data_dir_opta = os.path.join(base_dir, 'data', 'opta')\n", "scripts_dir = os.path.join(base_dir, 'scripts')\n", "scripts_dir_second_spectrum = os.path.join(base_dir, 'scripts', 'second_spectrum')\n", "scripts_dir_metrica_sports = os.path.join(base_dir, 'scripts', 'metrica_sports')\n", "models_dir = os.path.join(base_dir, 'models')\n", "img_dir = os.path.join(base_dir, 'img')\n", "fig_dir = os.path.join(base_dir, 'img', 'fig')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Create Directory Structure" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "\"\\n# Make the directory structure\\nfor folder in ['combined', 'competitions', 'events', 'tactics', 'lineups', 'three-sixty']:\\n path = os.path.join(data_dir, 'raw', folder)\\n if not os.path.exists(path):\\n os.mkdir(path)\\n\"" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "\"\"\"\n", "# Make the directory structure\n", "for folder in ['combined', 'competitions', 'events', 'tactics', 'lineups', 'three-sixty']:\n", " path = os.path.join(data_dir, 'raw', folder)\n", " if not os.path.exists(path):\n", " os.mkdir(path)\n", "\"\"\"" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Custom Functions" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [], "source": [ "# ADD CODE HERE IF REQUIRED" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Notebook Settings" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [], "source": [ "# Display all columns of displayed pandas DataFrames\n", "pd.set_option('display.max_columns', None)\n", "#pd.set_option('display.max_rows', None)\n", "pd.options.mode.chained_assignment = None" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "---\n", "\n", "\n", "\n", "## 2. Notebook Brief\n", "This notebook parses and engineers [Opta data](https://www.statsperform.com/opta/) by [Stats Perform](https://www.statsperform.com/) ... using [pandas](http://pandas.pydata.org/).\n", "\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_`." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "---\n", "\n", "\n", "\n", "## 3. Data Sources" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "\n", "### 3.1. Introduction\n", "[Opta data](https://www.statsperform.com/opta/) by [Stats Perform](https://www.statsperform.com/) is... football analytics, data provider ... \n", "\n", "F24 data is... F7 data is...\n", "\n", "![Opta](../../img/logos/opta_sports_logo_small.png)\n", "\n", "![Stats Perform](../../img/logos/stats_perform_logo_small.png)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "\n", "### 3.2. Import Data\n", "The following cells read in previously parsed `XML` files that have been saved as `CSV` files, using [FC.rSTATS](https://twitter.com/FC_rstats)'s `parse_f24` and `parse_f7` functions (see the following for more info [[link](http://www.fcrstats.com/fcrstats_package.html)]). These `CSV` files are read in as [pandas](https://pandas.pydata.org/) DataFrames." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "\n", "#### 3.2.1. F7 Files\n", "The each of the two parsed F7 data has been save into the following four files:\n", "* Game data\n", "* Players data\n", "* Goals data\n", "* Bookings data\n", "\n", "Two matches are available. There are therefore are 8 F7 files to import in total." ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "['../../data/opta/raw/F7/srml-8-2021-f2210324-matchresults-bookings.csv', '../../data/opta/raw/F7/srml-8-2021-f2210324-matchresults-goals.csv', '../../data/opta/raw/F7/srml-8-2021-f2210334-matchresults-players.csv', '../../data/opta/raw/F7/srml-8-2021-f2210334-matchresults-bookings.csv', '../../data/opta/raw/F7/srml-8-2021-f2210324-matchresults-gamedata.csv', '../../data/opta/raw/F7/srml-8-2021-f2210334-matchresults-goals.csv', '../../data/opta/raw/F7/srml-8-2021-f2210324-matchresults-players.csv', '../../data/opta/raw/F7/srml-8-2021-f2210334-matchresults-gamedata.csv']\n" ] } ], "source": [ "# Show files in directory\n", "print(glob.glob(os.path.join(data_dir_opta, 'raw', 'F7/*.csv')))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The two datasets provided are for the following matches:\n", "* [27/09/2021: Crystal Palace (1) vs. (1) Brighton & Hove Albion](https://www.bbc.co.uk/sport/football/58620544) (f2210324)\n", "* [03/10/2021: Crystal Palace (2) vs. (2) Leicester City](https://www.bbc.co.uk/sport/football/58667896) (f2210334)" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [], "source": [ "# Import CSV files as pandas DataFrames\n", "\n", "## 27/09/2021: Crystal Palace (1) vs. (1) Brighton & Hove Albion (f2210324)\n", "df_cry_bri_game_raw = pd.read_csv(os.path.join(data_dir_opta, 'raw', 'F7', 'srml-8-2021-f2210324-matchresults-gamedata.csv'))\n", "df_cry_bri_players_raw = pd.read_csv(os.path.join(data_dir_opta, 'raw', 'F7', 'srml-8-2021-f2210324-matchresults-players.csv'))\n", "df_cry_bri_goals_raw = pd.read_csv(os.path.join(data_dir_opta, 'raw', 'F7', 'srml-8-2021-f2210324-matchresults-goals.csv'))\n", "df_cry_bri_bookings_raw = pd.read_csv(os.path.join(data_dir_opta, 'raw', 'F7', 'srml-8-2021-f2210324-matchresults-bookings.csv'))\n", "\n", "## 03/10/2021: Crystal Palace (2) vs. (2) Leicester City (f2210334)\n", "df_cry_lei_game_raw = pd.read_csv(os.path.join(data_dir_opta, 'raw', 'F7', 'srml-8-2021-f2210334-matchresults-gamedata.csv'))\n", "df_cry_lei_players_raw = pd.read_csv(os.path.join(data_dir_opta, 'raw', 'F7', 'srml-8-2021-f2210334-matchresults-players.csv'))\n", "df_cry_lei_goals_raw = pd.read_csv(os.path.join(data_dir_opta, 'raw', 'F7', 'srml-8-2021-f2210334-matchresults-goals.csv'))\n", "df_cry_lei_bookings_raw = pd.read_csv(os.path.join(data_dir_opta, 'raw', 'F7', 'srml-8-2021-f2210334-matchresults-bookings.csv'))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "\n", "#### 3.2.2. F24 Files\n", "Each of the two matches has a single Event file. There are therefore 2 F24 files to import in total." ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "['../../data/opta/raw/F24/f24-8-2021-2210334-eventdetails.csv', '../../data/opta/raw/F24/f24-8-2021-2210324-eventdetails.csv']\n" ] } ], "source": [ "# Show files in directory\n", "print(glob.glob(os.path.join(data_dir_opta, 'raw', 'F24/*.csv')))" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [], "source": [ "# Import CSV files as pandas DataFrames\n", "\n", "## 27/09/2021: Crystal Palace (1) vs. (1) Brighton & Hove Albion (f2210324)\n", "df_cry_bri_events_raw = pd.read_csv(os.path.join(data_dir_opta, 'raw', 'F24', 'f24-8-2021-2210324-eventdetails.csv'))\n", "\n", "## 03/10/2021: Crystal Palace (2) vs. (2) Leicester City (f2210334)\n", "df_cry_lei_events_raw = pd.read_csv(os.path.join(data_dir_opta, 'raw', 'F24', 'f24-8-2021-2210334-eventdetails.csv'))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "\n", "### 3.3. Initial Data Handling\n", "To avoid duplication commands, this section just goes through the first of the two Event files, [Crystal Palace vs. Leicester City](https://www.bbc.co.uk/sport/football/58620544) (f2210334).\n", "\n", "First check the 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": 11, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
Unnamed: 0idevent_idtype_idperiod_idminsecteam_idoutcomexytimestamplast_modifiedversionplayer_idkeypassassist1102103107108123124127131301311391401411441451461471515215315415515615716716817170173174177178179181801821831851891941961971992202092121021121221321421522223224225227228229230231233236237242402412525025525625725926527928528628729292293294295330302313283463473633743753763773783833843853863873883893913923933953963973994406414244458464749553555657596636465772737475767880818283888994
01233864464713416001310.00.02021-10-03T13:00:03.3702021-10-03T14:00:201633266020074NaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN2.01, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0, 0, 0, 0,...NaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN17745.0NaN4973.0NaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0...NaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN17745, 166477, 40146, 197469, 218031, 93100, 2...NaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN1, 2, 2, 3, 2, 2, 3, 3, 4, 4, 3, 5, 5, 5, 5, 5...NaNNaNNaNNaNNaNNaNNaNNaNNaN1, 27, 5, 20, 4, 23, 37, 8, 9, 14, 7, 10, 11, ...NaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN
12233864467713416003110.00.02021-10-03T13:00:06.3942021-10-03T13:54:211633265661489NaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN4.01, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0, 0, 0, 0,...NaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN66975.0NaN406.0NaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0...NaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN40836, 55494, 244723, 66975, 174874, 209036, 2...NaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN1, 2, 2, 3, 2, 2, 3, 3, 4, 4, 4, 5, 5, 5, 5, 5...NaNNaNNaNNaNNaNNaNNaNNaNNaN13, 2, 3, 4, 16, 6, 23, 18, 22, 9, 11, 1, 5, 7...NaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN
2323386962392321003110.00.02021-10-03T14:00:24.4952021-10-03T22:13:381633295617200NaNNaNNaNNaNNaNNaNNaNNaNNaNNaNRight to LeftNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN
3423386962452321001310.00.02021-10-03T14:00:24.4952021-10-03T22:13:391633295617265NaNNaNNaNNaNNaNNaNNaNNaNNaNNaNLeft to RightNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN
4523386962993110031150.250.02021-10-03T14:00:24.5762021-10-03T22:27:55163329647495650471.0NaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN33.149.0NaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN-1.0NaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN18.03.2NaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNSNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNBackNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN
\n", "
" ], "text/plain": [ " Unnamed: 0 id event_id type_id period_id min sec team_id \\\n", "0 1 2338644647 1 34 16 0 0 13 \n", "1 2 2338644677 1 34 16 0 0 31 \n", "2 3 2338696239 2 32 1 0 0 31 \n", "3 4 2338696245 2 32 1 0 0 13 \n", "4 5 2338696299 3 1 1 0 0 31 \n", "\n", " outcome x y timestamp last_modified \\\n", "0 1 0.0 0.0 2021-10-03T13:00:03.370 2021-10-03T14:00:20 \n", "1 1 0.0 0.0 2021-10-03T13:00:06.394 2021-10-03T13:54:21 \n", "2 1 0.0 0.0 2021-10-03T14:00:24.495 2021-10-03T22:13:38 \n", "3 1 0.0 0.0 2021-10-03T14:00:24.495 2021-10-03T22:13:39 \n", "4 1 50.2 50.0 2021-10-03T14:00:24.576 2021-10-03T22:27:55 \n", "\n", " version player_id keypass assist 1 102 103 107 108 123 \\\n", "0 1633266020074 NaN NaN NaN NaN NaN NaN NaN NaN NaN \n", "1 1633265661489 NaN NaN NaN NaN NaN NaN NaN NaN NaN \n", "2 1633295617200 NaN NaN NaN NaN NaN NaN NaN NaN NaN \n", "3 1633295617265 NaN NaN NaN NaN NaN NaN NaN NaN NaN \n", "4 1633296474956 50471.0 NaN NaN NaN NaN NaN NaN NaN NaN \n", "\n", " 124 127 13 130 \\\n", "0 NaN NaN NaN 2.0 \n", "1 NaN NaN NaN 4.0 \n", "2 NaN Right to Left NaN NaN \n", "3 NaN Left to Right NaN NaN \n", "4 NaN NaN NaN NaN \n", "\n", " 131 139 140 141 144 \\\n", "0 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0, 0, 0, 0,... NaN NaN NaN NaN \n", "1 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0, 0, 0, 0,... NaN NaN NaN NaN \n", "2 NaN NaN NaN NaN NaN \n", "3 NaN NaN NaN NaN NaN \n", "4 NaN NaN 33.1 49.0 NaN \n", "\n", " 145 146 147 15 152 153 154 155 156 157 167 168 17 170 173 \\\n", "0 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN \n", "1 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN \n", "2 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN \n", "3 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN \n", "4 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN \n", "\n", " 174 177 178 179 18 180 182 183 185 189 194 196 197 199 \\\n", "0 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 17745.0 NaN 4973.0 NaN \n", "1 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 66975.0 NaN 406.0 NaN \n", "2 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN \n", "3 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN \n", "4 NaN NaN -1.0 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN \n", "\n", " 2 20 209 21 210 211 212 213 214 215 22 223 224 225 \\\n", "0 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN \n", "1 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN \n", "2 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN \n", "3 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN \n", "4 NaN NaN NaN NaN NaN NaN 18.0 3.2 NaN NaN NaN NaN NaN NaN \n", "\n", " 227 228 229 230 231 233 \\\n", "0 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0... NaN NaN NaN NaN NaN \n", "1 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0... NaN NaN NaN NaN NaN \n", "2 NaN NaN NaN NaN NaN NaN \n", "3 NaN NaN NaN NaN NaN NaN \n", "4 NaN NaN NaN NaN NaN NaN \n", "\n", " 236 237 24 240 241 25 250 255 256 257 259 265 279 285 286 \\\n", "0 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN \n", "1 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN \n", "2 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN \n", "3 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN \n", "4 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN S NaN NaN \n", "\n", " 287 29 292 293 294 295 3 \\\n", "0 NaN NaN NaN NaN NaN NaN NaN \n", "1 NaN NaN NaN NaN NaN NaN NaN \n", "2 NaN NaN NaN NaN NaN NaN NaN \n", "3 NaN NaN NaN NaN NaN NaN NaN \n", "4 NaN NaN NaN NaN NaN NaN NaN \n", "\n", " 30 302 31 328 346 347 \\\n", "0 17745, 166477, 40146, 197469, 218031, 93100, 2... NaN NaN NaN NaN NaN \n", "1 40836, 55494, 244723, 66975, 174874, 209036, 2... NaN NaN NaN NaN NaN \n", "2 NaN NaN NaN NaN NaN NaN \n", "3 NaN NaN NaN NaN NaN NaN \n", "4 NaN NaN NaN NaN NaN NaN \n", "\n", " 363 374 375 376 377 378 383 384 385 386 387 388 389 391 392 \\\n", "0 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN \n", "1 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN \n", "2 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN \n", "3 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN \n", "4 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN \n", "\n", " 393 395 396 397 399 4 406 41 42 \\\n", "0 NaN NaN NaN NaN NaN NaN NaN NaN NaN \n", "1 NaN NaN NaN NaN NaN NaN NaN NaN NaN \n", "2 NaN NaN NaN NaN NaN NaN NaN NaN NaN \n", "3 NaN NaN NaN NaN NaN NaN NaN NaN NaN \n", "4 NaN NaN NaN NaN NaN NaN NaN NaN NaN \n", "\n", " 44 458 46 47 49 5 53 \\\n", "0 1, 2, 2, 3, 2, 2, 3, 3, 4, 4, 3, 5, 5, 5, 5, 5... NaN NaN NaN NaN NaN NaN \n", "1 1, 2, 2, 3, 2, 2, 3, 3, 4, 4, 4, 5, 5, 5, 5, 5... NaN NaN NaN NaN NaN NaN \n", "2 NaN NaN NaN NaN NaN NaN NaN \n", "3 NaN NaN NaN NaN NaN NaN NaN \n", "4 NaN NaN NaN NaN NaN NaN NaN \n", "\n", " 55 56 57 59 6 63 \\\n", "0 NaN NaN NaN 1, 27, 5, 20, 4, 23, 37, 8, 9, 14, 7, 10, 11, ... NaN NaN \n", "1 NaN NaN NaN 13, 2, 3, 4, 16, 6, 23, 18, 22, 9, 11, 1, 5, 7... NaN NaN \n", "2 NaN NaN NaN NaN NaN NaN \n", "3 NaN NaN NaN NaN NaN NaN \n", "4 NaN Back NaN NaN NaN NaN \n", "\n", " 64 65 7 72 73 74 75 76 78 80 81 82 83 88 89 94 \n", "0 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN \n", "1 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN \n", "2 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN \n", "3 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN \n", "4 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN " ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Display the first five rows of the DataFrame, df_cry_lei_events_raw\n", "df_cry_lei_events_raw.head()" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
Unnamed: 0idevent_idtype_idperiod_idminsecteam_idoutcomexytimestamplast_modifiedversionplayer_idkeypassassist1102103107108123124127131301311391401411441451461471515215315415515615716716817170173174177178179181801821831851891941961971992202092121021121221321421522223224225227228229230231233236237242402412525025525625725926527928528628729292293294295330302313283463473633743753763773783833843853863873883893913923933953963973994406414244458464749553555657596636465772737475767880818283888994
196019612339193269189383276103116.896.22021-10-03T15:35:16.1172021-10-04T01:47:401633308458373244723.0NaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN219352.0NaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN
196119622339194665189583123931147.286.72021-10-03T14:03:04.3042021-10-04T01:51:14163330867353450471.0NaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN219352.0NaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN
19621963233919789512891276213192.022.22021-10-03T15:35:08.4362021-10-04T02:03:551633309435556219352.0NaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN86.934.3NaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN-1.0NaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN9.82.1NaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNCenterNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN
1963196423391981931290611141113130.730.62021-10-03T14:14:36.3452021-10-04T02:05:111633309511458197469.0NaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN-1.0NaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNBackNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN
19641965236955330918962416003110.00.02021-10-03T14:00:14.4952021-12-22T16:08:011640189281031NaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN-1.00.00.00.0NaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN0.0NaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN5.04.022445.0NaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN
\n", "
" ], "text/plain": [ " Unnamed: 0 id event_id type_id period_id min sec team_id \\\n", "1960 1961 2339193269 1893 83 2 76 10 31 \n", "1961 1962 2339194665 1895 83 1 2 39 31 \n", "1962 1963 2339197895 1289 1 2 76 2 13 \n", "1963 1964 2339198193 1290 61 1 14 11 13 \n", "1964 1965 2369553309 1896 24 16 0 0 31 \n", "\n", " outcome x y timestamp last_modified \\\n", "1960 1 6.8 96.2 2021-10-03T15:35:16.117 2021-10-04T01:47:40 \n", "1961 1 47.2 86.7 2021-10-03T14:03:04.304 2021-10-04T01:51:14 \n", "1962 1 92.0 22.2 2021-10-03T15:35:08.436 2021-10-04T02:03:55 \n", "1963 1 30.7 30.6 2021-10-03T14:14:36.345 2021-10-04T02:05:11 \n", "1964 1 0.0 0.0 2021-10-03T14:00:14.495 2021-12-22T16:08:01 \n", "\n", " version player_id keypass assist 1 102 103 107 108 123 \\\n", "1960 1633308458373 244723.0 NaN NaN NaN NaN NaN NaN NaN NaN \n", "1961 1633308673534 50471.0 NaN NaN NaN NaN NaN NaN NaN NaN \n", "1962 1633309435556 219352.0 NaN NaN NaN NaN NaN NaN NaN NaN \n", "1963 1633309511458 197469.0 NaN NaN NaN NaN NaN NaN NaN NaN \n", "1964 1640189281031 NaN NaN NaN NaN NaN NaN NaN NaN NaN \n", "\n", " 124 127 13 130 131 139 140 141 144 145 146 147 15 152 \\\n", "1960 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN \n", "1961 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN \n", "1962 NaN NaN NaN NaN NaN NaN 86.9 34.3 NaN NaN NaN NaN NaN NaN \n", "1963 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN \n", "1964 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN \n", "\n", " 153 154 155 156 157 167 168 17 170 173 174 177 178 179 18 \\\n", "1960 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN \n", "1961 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN \n", "1962 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN -1.0 NaN NaN \n", "1963 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN -1.0 NaN NaN \n", "1964 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN \n", "\n", " 180 182 183 185 189 194 196 197 199 2 20 209 21 210 211 \\\n", "1960 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN \n", "1961 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN \n", "1962 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN \n", "1963 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN \n", "1964 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN \n", "\n", " 212 213 214 215 22 223 224 225 227 228 229 230 231 233 \\\n", "1960 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN \n", "1961 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN \n", "1962 9.8 2.1 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN \n", "1963 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN \n", "1964 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN \n", "\n", " 236 237 24 240 241 25 250 255 256 257 259 265 279 285 286 \\\n", "1960 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN \n", "1961 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN \n", "1962 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN \n", "1963 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN \n", "1964 NaN NaN NaN NaN NaN NaN NaN -1.0 0.0 0.0 0.0 NaN NaN NaN NaN \n", "\n", " 287 29 292 293 294 295 3 30 302 31 328 346 347 363 374 \\\n", "1960 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN \n", "1961 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN \n", "1962 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN \n", "1963 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN \n", "1964 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 0.0 NaN \n", "\n", " 375 376 377 378 383 384 385 386 387 388 389 391 392 393 \\\n", "1960 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN \n", "1961 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN \n", "1962 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN \n", "1963 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN \n", "1964 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN \n", "\n", " 395 396 397 399 4 406 41 42 44 458 46 47 49 \\\n", "1960 NaN NaN NaN 219352.0 NaN NaN NaN NaN NaN NaN NaN NaN NaN \n", "1961 NaN NaN NaN 219352.0 NaN NaN NaN NaN NaN NaN NaN NaN NaN \n", "1962 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN \n", "1963 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN \n", "1964 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 5.0 4.0 22445.0 \n", "\n", " 5 53 55 56 57 59 6 63 64 65 7 72 73 74 75 76 78 \\\n", "1960 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN \n", "1961 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN \n", "1962 NaN NaN NaN Center NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN \n", "1963 NaN NaN NaN Back NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN \n", "1964 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN \n", "\n", " 80 81 82 83 88 89 94 \n", "1960 NaN NaN NaN NaN NaN NaN NaN \n", "1961 NaN NaN NaN NaN NaN NaN NaN \n", "1962 NaN NaN NaN NaN NaN NaN NaN \n", "1963 NaN NaN NaN NaN NaN NaN NaN \n", "1964 NaN NaN NaN NaN NaN NaN NaN " ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Display the last five rows of the DataFrame, df_cry_lei_events_raw\n", "df_cry_lei_events_raw.tail()" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "(1965, 162)\n" ] } ], "source": [ "# Print the shape of the DataFrame, df_cry_lei_events_raw\n", "print(df_cry_lei_events_raw.shape)" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Index(['Unnamed: 0', 'id', 'event_id', 'type_id', 'period_id', 'min', 'sec',\n", " 'team_id', 'outcome', 'x',\n", " ...\n", " '75', '76', '78', '80', '81', '82', '83', '88', '89', '94'],\n", " dtype='object', length=162)\n" ] } ], "source": [ "# Print the column names of the DataFrame, df_cry_lei_events_raw\n", "print(df_cry_lei_events_raw.columns)" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Unnamed: 0 int64\n", "id int64\n", "event_id int64\n", "type_id int64\n", "period_id int64\n", " ... \n", "82 float64\n", "83 float64\n", "88 float64\n", "89 float64\n", "94 float64\n", "Length: 162, dtype: object" ] }, "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Data types of the features of the raw DataFrame, df_cry_lei_events_raw\n", "df_cry_lei_events_raw.dtypes" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Full details of these attributes and their data types is discussed further in the [Data Dictionary](section3.2.2)." ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Unnamed: 0 int64\n", "id int64\n", "event_id int64\n", "type_id int64\n", "period_id int64\n", "min int64\n", "sec int64\n", "team_id int64\n", "outcome int64\n", "x float64\n", "y float64\n", "timestamp object\n", "last_modified object\n", "version int64\n", "player_id float64\n", "keypass float64\n", "assist float64\n", "1 float64\n", "102 float64\n", "103 float64\n", "107 float64\n", "108 float64\n", "123 float64\n", "124 float64\n", "127 object\n", "13 float64\n", "130 float64\n", "131 object\n", "139 float64\n", "140 float64\n", "141 float64\n", "144 float64\n", "145 float64\n", "146 float64\n", "147 float64\n", "15 float64\n", "152 float64\n", "153 float64\n", "154 float64\n", "155 float64\n", "156 float64\n", "157 float64\n", "167 float64\n", "168 float64\n", "17 float64\n", "170 float64\n", "173 float64\n", "174 float64\n", "177 float64\n", "178 float64\n", "179 float64\n", "18 float64\n", "180 float64\n", "182 float64\n", "183 float64\n", "185 float64\n", "189 float64\n", "194 float64\n", "196 float64\n", "197 float64\n", "199 float64\n", "2 float64\n", "20 float64\n", "209 float64\n", "21 float64\n", "210 float64\n", "211 float64\n", "212 float64\n", "213 float64\n", "214 float64\n", "215 float64\n", "22 float64\n", "223 float64\n", "224 float64\n", "225 float64\n", "227 object\n", "228 float64\n", "229 float64\n", "230 float64\n", "231 float64\n", "233 float64\n", "236 float64\n", "237 float64\n", "24 float64\n", "240 float64\n", "241 float64\n", "25 float64\n", "250 float64\n", "255 float64\n", "256 float64\n", "257 float64\n", "259 float64\n", "265 float64\n", "279 object\n", "285 float64\n", "286 float64\n", "287 float64\n", "29 float64\n", "292 float64\n", "293 float64\n", "294 float64\n", "295 float64\n", "3 float64\n", "30 object\n", "302 float64\n", "31 float64\n", "328 float64\n", "346 float64\n", "347 float64\n", "363 float64\n", "374 object\n", "375 object\n", "376 float64\n", "377 float64\n", "378 float64\n", "383 float64\n", "384 float64\n", "385 float64\n", "386 float64\n", "387 float64\n", "388 float64\n", "389 float64\n", "391 float64\n", "392 float64\n", "393 float64\n", "395 float64\n", "396 float64\n", "397 float64\n", "399 float64\n", "4 float64\n", "406 object\n", "41 object\n", "42 float64\n", "44 object\n", "458 float64\n", "46 float64\n", "47 float64\n", "49 float64\n", "5 float64\n", "53 float64\n", "55 float64\n", "56 object\n", "57 float64\n", "59 object\n", "6 float64\n", "63 float64\n", "64 float64\n", "65 float64\n", "7 float64\n", "72 float64\n", "73 float64\n", "74 float64\n", "75 float64\n", "76 float64\n", "78 float64\n", "80 float64\n", "81 float64\n", "82 float64\n", "83 float64\n", "88 float64\n", "89 float64\n", "94 float64\n", "dtype: object\n" ] } ], "source": [ "# Displays all columns\n", "with pd.option_context('display.max_rows', None, 'display.max_columns', None):\n", " print(df_cry_lei_events_raw.dtypes)" ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "\"\\n# Print statements about the dataset\\n\\n## Define variables for print statments\\ncount_events = len(df_cry_lei_events)\\ncount_shots = len(df_cry_lei_events[(df_cry_lei_events['type_name'] == 'Shot')])\\ncount_goals = len(df_cry_lei_events[(df_cry_lei_events['type_name'] == 'Shot') & (df_cry_lei_events['shot_outcome_name'] == 'Goal')])\\ncols = list(df_cry_lei_events)\\ncount_event_type = len(df_cry_lei_events['type_name'].unique())\\nvals_event_type = df_cry_lei_events['type_name'].unique()\\n\\n## Print statements\\nprint(f'The EURO 2020 Events DataFrame contains the data for {count_matches:,} matches, of which there are {count_events:,} total events.\\n')\\nprint(f'Of these events, there are {count_shots:,} shots ({round(100*count_shots/count_events,1)}%) and {count_goals:,} goals ({round(100*count_goals/count_events,1)}%).\\n')\\nprint(f'This translates to a shot to goal conversion percentage of {round(100*count_goals/count_shots, 1)}%.\\n')\\nprint(f'The dataset contains the following features: {cols}\\n')\\nprint(f'The 'event_type' column contain {count_event_type:,} different values, including the following: {vals_event_type}\\n') \\n\"" ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ "\"\"\"\n", "# Print statements about the dataset\n", "\n", "## Define variables for print statments\n", "count_events = len(df_cry_lei_events)\n", "count_shots = len(df_cry_lei_events[(df_cry_lei_events['type_name'] == 'Shot')])\n", "count_goals = len(df_cry_lei_events[(df_cry_lei_events['type_name'] == 'Shot') & (df_cry_lei_events['shot_outcome_name'] == 'Goal')])\n", "cols = list(df_cry_lei_events)\n", "count_event_type = len(df_cry_lei_events['type_name'].unique())\n", "vals_event_type = df_cry_lei_events['type_name'].unique()\n", "\n", "## Print statements\n", "print(f'The EURO 2020 Events DataFrame contains the data for {count_matches:,} matches, of which there are {count_events:,} total events.\\n')\n", "print(f'Of these events, there are {count_shots:,} shots ({round(100*count_shots/count_events,1)}%) and {count_goals:,} goals ({round(100*count_goals/count_events,1)}%).\\n')\n", "print(f'This translates to a shot to goal conversion percentage of {round(100*count_goals/count_shots, 1)}%.\\n')\n", "print(f'The dataset contains the following features: {cols}\\n')\n", "print(f'The \\'event_type\\' column contain {count_event_type:,} different values, including the following: {vals_event_type}\\n') \n", "\"\"\"" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Counts of the event types:" ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [], "source": [ "# Shot outcomes types and their frequency\n", "#df_cry_lei_events_raw.groupby(['type_name']).type_name.count()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "There are eight outcomes of a shot: 'Blocked', 'Goal', 'Off T', 'Post', 'Saved', 'Saved Off Target', 'Saved to Post', 'Wayward'." ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [], "source": [ "# Filter DataFrame for only shots and then groupby the 'typeName' (Event type) and count the number of each\n", "#df_cry_lei_events_raw[(df_cry_lei_events['type_name'] == 'Shot')].groupby(['shot_type_name']).shot_type_name.count()" ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "RangeIndex: 1965 entries, 0 to 1964\n", "Columns: 162 entries, Unnamed: 0 to 94\n", "dtypes: float64(138), int64(10), object(14)\n", "memory usage: 2.4+ MB\n" ] } ], "source": [ "# Info for the raw DataFrame, df_cry_lei_events_raw\n", "df_cry_lei_events_raw.info()" ] }, { "cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 21, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": "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euutce+99zYspo985CPDpi+88MI46KCDGlZ+K5CQg4z09vZGhHFtmpWxixqv2vfc+1lfxk8jr9TD7UEyFRhKnQAAtIskSWKXXXaJGTNmDJs31JIlSxqakNtpp50iTdMol8sxc+bM2GOPPRpWdquQkIOMDJ78c1AJ1dFSCwAAAIB2cNttt8V5552XdRjDfOMb38g6hKYnIQcAG6DVW5BJhAIAsKGq2WeOiKbebwaAetpzzz3jpJNOivnz56+zLE3TUZ87dPn61h067y9/+Us8/PDDY8Zz+OGHj7kOY5OQA6iBsYsY1OoJq1ZPONK81MPtwXhRVMvJfsi3Vt9nBoB66+joiLPOOmvcz3vhhRdi5cqVkSRJJEkSf/jDH+ILX/hCRESlu8nBx2maRqlUqmq7119/fVx//fWjrnPeeefFscceO+6Y24mEHDBuTtAbuwgga+rh9uDkLdVysh8AgFazZMmSSnKtUChEoVCIJEkqybTe3t749Kc/nXWYFQ888ICE3Bgk5IBxc8JDywyArKmHAcgDLXmB8XJOBajGnXfeGR/4wAcyjeGUU06pPD7ggANir732yjCa1iAhB1ADLTMAsqUeBiAPnFQHxks3y0A1dt111zj00EPjwQcfjHK5HAMDA9Hf3x99fX2xatWqSteTE+Woo46K0047bULLaEcScgA10DKDduHqTfJKPQwAQDNyjAVU484774wbbrihoWW+7GUviyRJYtKkSfGOd7yjoWW3Cwk5gIwZkw8A1k9XcETYVwKgtWghB+TRtttuG4ccckgUCoUoFovx29/+NpIkiYhY535ta88faf3JkyfH4YcfHsVisd7hNw0JOYCMuToOAAAAABj06le/Onp6eobNK5fLUS6Xo1QqRalUii9/+ctxzTXX1KW8J554Iv7rv/6rLtsazdKlS+NNb3rThJeTVxJyADUwdhFAttTD7cEFK0S4eGk8tColr7QIAoANVygUolAoxKRJq9M6v//97ye0vBNPPLHyOE3TYfdrz1/b+tafOnVqvOENb6h3mE1FQg4y0tvbGxGNO0lY7YlLB0AAw+kqDYBmIXFJXkmsA0D9fe9734v//d//jSRJoqurK6677rqYN29e3bb/y1/+MkqlUpTL5Tj55JPj3e9+d9223a4k5CAjgydvG3VQ4gCovsbzfnrfobmpP/NJPdwetPahWlrfAADQ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rbbaKtPyv/zlL8esWbMyjaEVSchBRhrdZaUrsIBa6CYMAAAAoLF233336OnpqXQvGRGVbicH75csWRKf/OQnY9myZbFq1ap49tln61b+bbfdJiE3ASTkAAAAAAAAciZJkigWixERlftB2223XXz961/foO3Pnz8/Tj311Hj1q18ds2bNiu7u7ujq6oqjjjpqg7bL+knIQUYa3WUlTIRGtp7S7SpZ0UoQAABaly4kgTxavHhxnHzyyQ0r7+abb46bb765Mv2FL3xhnXWSJIkkSdZ5nKbpsPtBhxxySJxxxhlRKBQiYnVCcbPNNpuQ+JuFhBxkpNFdVsJEaGRXqLpdJSu+ewAA0Lrs7wN5tGzZsqxDWEeapusk3Ubzm9/8Jn7zm98Mm/ehD30o/vqv/7reoTUNCTkAAAAAAICc2HnnnaOnp2fUde688874wAc+0KCIxq+7uzumTZtWmd5kk03i1a9+dYYRZU9CDgAAAAAAoInsueeew5J2g+PBTZSxEoSMTUIOAADIpdmzZ4+6fHBMF+M8YvwfAADa3fbbbx+f+9zn4pFHHon+/v7o6+uLO+64I26//fa6bH/OnDmVx1OnTo3//u//ji222KIu224XEnIAAEAuVTuei3FfMP4PAACs3i8eehHaj3/84wkpZ/ny5fHkk09KyI2ThBwAAAAAAEATS9M07r333li2bFmkaRoREWeccUbcc8890d/fH6VSKQYGBiq3UqkUixYtiocffnjMbe+0007xjW98Y6JfQsuTkAMAAAAAAGhi9913X5x11ll12daxxx4bb3nLW6JYLEapVIrp06fXZbvtTkIOABiRLsAAoHlUM+6icfTIgnEeAWB8Fi5cGG95y1syK/+aa66Ja665Zti8np6ejKJpHYWsAwAAAAAAAGC1F154IesQmABayAEAI6rmamZXMgNAPmjVTl7pdQEAxmfp0qVZhzDMZpttlnUILUFCDqAG4zmgdOBJM3PyhLxSDwMA0IwcYwHV2GmnnRpe5l577RVpmkZERJqmldvg9JlnnlmZ3mabbeK8886LyZMnNzzOZiYhB21irFYuEVq6jEe172dEaF0EMAHUwwAANCNjKgLV+POf/9zwMv/0pz9Vve59990Xhx9+eBx88METGFHrkZCDNuEKrPpq9ZYZErgM0mUledXq9TAAAADta9ddd42enp5xPeeOO+6Ic889d4Iiirj00ksjSZJIkiSmTJkS22+//YSV1aok5CAjvb29EeGq/WbV6i0z8pjAlSQEhmr1ehgAAID2NW/evDj99NOzDqPihBNOiFe84hVZh9H0JOQgI4Mn//KW9KA69WyZoQVSdfKYJGwH3nfySgs5AACakWMsoBoPPvhg1iEMc9VVV8UHPvCBrMNoehJyADWod8sMO+PklYQxeaWFHAAAzcgYckA1dtppp4aW9573vCdOPPHESpeUhUIhIiIKhUJlHhtOQg4AAAAAACAnttxyy5gxY0YsWbKkIeXde++9sfvuu1eScaVSKVatWhWrVq2Kvr6+eNnLXhYvfelLGxJLK5OQAwAAAAAAyIlNN900rrjiinE955577omzzjqrpvJ+97vfxe9+97tR1+np6alp27xIQg4AAAAAAKCJ7b777vG9730vnn322Uo3kxdccEEsWrQo69BYQ0IOoAbjGffN+HA0M2Mcklfq4fYwe/bsUZcbA7A9GM8UAADG9pe//CU+85nPxNy5cyMiIk3TGBgYqOq5u+66a5xwwgnR0dERhUIhZs+eHcVicSLDbUsScgA1GOvEUMSLAzE7gUQzcxKUvFIPtwfJVCJcHAIAANXo7e2N3t7emp47b968+MxnPlOZvv/+++PMM8+sU2QMkpADAAAAAABoYltttdUGPX+XXXaJiIhisRgnnHBCHSJibRJykJHBqxVctQ/VqbY1jN8MvKia7v4i/BflkToPAACA0Vx55ZXxxS9+sW7bW758eaRpGgsXLoy3vvWtG7y9PffcMz7zmc9EZ2dnHaJrDRJykJHBE2iN6n7HiT2ane6qsuF9b27GWGtefnsAAACMZo899qjr9p566qm6bu/OO++MVatWScgNISEHbcKJvfoaz/vpfQeoP/Vwe6imlaeLiaB9qBMAAF60yy67RE9PT2X6gQceiPe+97112famm24aX/va16JYLEahUKjcBqeTJBn2mOpIyAHUoNoWhxG6gqO5jfVd9x0mK+rh9iCZCgylTgAAGNnGG29ct20988wzcfLJJw+bNzT5R20k5ABqoGUGQLbUw+1BaxgiXBwCQ6kXAYCR9PX1Tdi2999//wnbdjuRkAMARqS7WwCA/LBfBgCM5PHHH6/5uVdddVVssskmdYyG9ZGQA6iBrtJoF1olkFfq4fbgxDMRLg4BAIBqbLPNNjU/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NSu22GKLWLx4cdahVNx+++2Vx3fccUfss88+cdhhh2UY0eiKxWJcfPHFccstt8SDDz4Yu+yySxxwwAFRLBZHfE6SJP8WEdfE6tZwG0XEKRExOyKOTdP06Yh4eq31+yNiYZqm91cTk4QcZGSwRYlWa81pPC0OfcYA9aceBgAAoFVNnz49/vd//3fUde666644++yzGxTRur7yla/Ef/3Xf1WmB1vPDXrta18bp5122qgJsIlWLBbjoIMOGmvMuKG2iojvrrn/S0TcGRFHp2n6i3rEIyEH46T7NiKqH5MvonHdkjYzv6v80t0t9Vav37t6GGBdg2N4jESdR1aq+f+PCN9PABiHJ598MtPyFy1aNOryyy+/PC6//PIoFAqVeesbI27o47GWrd1F5vrGl4uI+Od//uea9ivSND11nOvvMJ71JeRgnJycph1Ue6LbGIetT7KUevN7B5g46lfyyv8/AIzfM888E6tWrYpSqRSlUinK5XLlcalUim233TY+//nPV+Y//vjj8cUvfjHrsNdRLpcbXuYPfvCDXJ6vkpADYB0OmAEAAAAgG7///e/jYx/7WNZhjMu2224bF1544Tot1tbXiq0e8yJWd5O5dleZaZrGRhttVPfXVw8ScgAAAAAAADnx/PPPZx3COn76059GoVCoJMQGu6IcvC8Wi+t0HclwEnIAwIi0lgSA5mEMOfLKGHIAMD6zZ8+O++67L+bPn79OC7CIqMwbev/UU0/F4sWLJyymadOmTdi224WEHAAwImPIAUDzcBENeeUiLwAYn6eeeiquvPLKTGM48sgjK+PTzZkzJ9NYWoWEHAAAAAAAQE6USqVMyz/uuOPi3HPPzTSGViQhBxnp7e2NiNDyBAAAAACAiuXLl2da/kte8pJMy29VEnKQkcFEm247AAAAAAAYtMcee8RPf/rT6OvrW+/yNE2jXC6vc/+jH/0o5s6dG2marnedtectXLhwvdufPn36BL669iUhBwAAAAAAkBP9/f3x7W9/Ox577LGqn/P444/HggULairv9NNPj7e85S01PZfqScgBAAAAAADkxJ133hlXXHFFw8r78Y9/HJ2dnZEkSURE5X6kx9XOGzrd3d0ds2fPjkKhUP8X0CQk5ABoCr29vaOOuRhh3EUAAAAAmt9GG23U0PKWLFkSl1566YSXs3jx4njTm9404eXklYQcQA32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OwCADfXrX/+6ruvRuvbee2/fAwAAWsYWW2wxrDvK9fnJT34Sn/vc5xoU0bruvffeuPfeezdoG9ddd92Yr7OVSMgB4+aEx/jeg3Z/r2hufu/klXoYAIBm5BgLqMbjjz8ef/d3f5d1GMN8+MMfjoiIJEkq84Y+XtvgstHWb7dGHRJyAAAAAAAAOfHss89mHcI6jjnmmKxDaHoScpCR3t7eiDDmSbMaq9vOCOPa1Fu177n3s750UVtf1YyH5f2sjnoYAIBmZNxToFmtPYbcd7/73Zg5c2ZG0TQnCTnIyOCOlW4KaGaNTNbo1oOs1PN77jsMAAD5IkEGUJu5c+dKyI2ThBxADYxdtJokGe3A9zyf1MPtQatSquVkKgC1sr8P5NEee+wRV111VfT19UVERJqmkaZp5fHQ+8HHTz/9dJxzzjkNi/GlL31pw8pqFRJykBFdVjY3XaWtpjtDICvq4fbg5BjVcjIVgFq5qAPIq0022WTc62+zzTaxYMGCCYpouCRJGlJOK5GQg4zospJW4OQXAAAAzcxxLdCsli5dGp/97Gejv78/Ojs749lnn21YMi4i4qabboqXvexlDSuvFUjIAQAAAAAANJGrr746brrppgnZdqFQiOOPPz66urqis7Mzurq6Ko87Oztj8803j/33339Cym5lEnIAAAAAAABN5B3veEfss88+sWrVqujr64tly5bF3LlzY/LkycO6kyyXy+u9lUqlWLBgQcydO3edbZfL5bjqqqtGLf/iiy+WlBsnCTkAAAAAAIAmUigUYq+99ho275hjjhnXNhYsWBBvfetbq1p30003jVKpFKVSKbbbbrvYbbfdxlUWEnIAAAAAAABNJ03TSou3wcdpmkapVIo0TeOhhx6KK664IorFYhQKhSgWi7HjjjtGd3d3DAwMxOOPP151Wd///veju7t7Al9N65OQAwAAAAAAyIkHHngg3vve92YdRsVJJ50UXV1dWYfR9CTkICO9vb0REfHBD35wxHU+//nPx957792QeAAAAAAAyN6MGTNik002ib/85S+ZlP+ud70rTjnllCgUCsPGo2PDSMhBRgYTbb/+9a8zjQMAAAAAgPzYbLPN4qqrrhrXcx555JF417veVZfyL7vssrjsssuGzevp6anLttuZhBwAAAAAAEBOpGka1157bSxatGjY/MHWakmSrNNy7dZbb21Y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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "# Plot visualisation of the missing values for each feature of the raw DataFrame, df_cry_lei_events_raw\n", "msno.matrix(df_cry_lei_events_raw, figsize = (30, 7))" ] }, { "cell_type": "code", "execution_count": 22, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "player_id 23\n", "keypass 1948\n", "assist 1964\n", "1 1809\n", "102 1938\n", " ... \n", "82 1958\n", "83 1961\n", "88 1964\n", "89 1964\n", "94 1958\n", "Length: 148, dtype: int64" ] }, "execution_count": 22, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Counts of missing values\n", "null_value_stats = df_cry_lei_events_raw.isnull().sum(axis=0)\n", "null_value_stats[null_value_stats != 0]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "---\n", "\n", "\n", "\n", "## 4. Data Engineering\n", "The next step is to wrangle the dataset to into a format that’s suitable for analysis.\n", "\n", "This section is broken down into the following subsections:\n", "\n", "4.01. [Assign Raw DataFrame to Engineered DataFrame](#section4.1)
\n", "4.02. [Rename Columns](#section4.2)
\n", "4.02. [Drop Duplicate Columns](#section4.3)
\n", "4.04. [Sort the DataFrame](#section4.4)
\n", "4.05. [Determine Each Player's Most Frequent Position](#section4.5)
\n", "4.06. [Determine Each Player's Total Minutes Played](#section4.6)
\n", "4.07. [Break Down All location Attributes](#section4.7)
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "\n", "### 4.01. Assign Raw DataFrames to Engineered DataFrames" ] }, { "cell_type": "code", "execution_count": 23, "metadata": {}, "outputs": [], "source": [ "# Import CSV files as pandas DataFrames\n", "\n", "## F7 data\n", "\n", "### 27/09/2021: Crystal Palace (1) vs. (1) Brighton & Hove Albion (f2210324)\n", "df_cry_bri_game = df_cry_bri_game_raw.copy()\n", "df_cry_bri_players = df_cry_bri_players_raw.copy()\n", "df_cry_bri_goals = df_cry_bri_goals_raw.copy()\n", "df_cry_bri_bookings = df_cry_bri_bookings_raw.copy()\n", "\n", "### 03/10/2021: Crystal Palace (2) vs. (2) Leicester City (f2210334)\n", "df_cry_lei_game = df_cry_lei_game_raw.copy()\n", "df_cry_lei_players = df_cry_lei_players_raw.copy()\n", "df_cry_lei_goals = df_cry_lei_goals_raw.copy()\n", "df_cry_lei_bookings = df_cry_lei_bookings_raw.copy()\n", "\n", "\n", "## F24 data\n", "\n", "### 27/09/2021: Crystal Palace (1) vs. (1) Brighton & Hove Albion (f2210324)\n", "df_cry_bri_events = df_cry_bri_events_raw.copy()\n", "\n", "### 03/10/2021: Crystal Palace (2) vs. (2) Leicester City (f2210334)\n", "df_cry_lei_events = df_cry_lei_events_raw.copy()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "\n", "### 4.02. Drop Columns" ] }, { "cell_type": "code", "execution_count": 24, "metadata": {}, "outputs": [], "source": [ "#df_cry_bri_events = df_cry_bri_events.drop('Unnamed: 0', axis=1)\n", "#df_cry_lei_events = df_cry_bri_events.drop('Unnamed: 0', axis=1)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "\n", "### 4.03. Sort DataFrames\n", "Sorting DataFrame into correct order of matches and their events by time and date. This is important as certain features created in the subsequent sections require logic that is dependent on proceeded and subsequent events and for these to be in the correct order." ] }, { "cell_type": "code", "execution_count": 25, "metadata": {}, "outputs": [], "source": [ "# Sort DataFrame by 'matchDate', 'startTime', 'matchId', 'minute', 'second', 'eventId' \n", "#df_cry_bri_events = df_opta_events.sort_values(['startTime', 'matchId', 'minute', 'second', 'eventId'], ascending=[True, True, True, True, True])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "\n", "### 4.04. Clean Event Types Columns\n", "Specifically with the `type_id` attribute of the Event data, there are 74 different types (65 as per the Opta F24 Appendices documentation).\n", "\n", "**Note:** there are 7 event types missing from the definitions list as they are not observed in the event data . The IDs of these Events are: 26, 29, 31, 33, 46, 48, 62.\n", "\n", "For the event types that were available in the documentation and observed in the event data, they have the following Ids and definitions ((see the Opta F24 Appendices document [[link](https://github.com/eddwebster/football_analytics/blob/master/docs/opta/f24_appendices.docx)].\n", "\n", "| No. | `typeName` | `typeId` | Definition |\n", "|-----------|-------------------------------------|----------------|-----------------------------------------------|\n", "| 1. | `Pass` | `1` | Any pass attempted from one player to another – free kicks, corners, throw ins, goal kicks and goal assists |\n", "| 2. | `Offside Pass` | `2` | Attempted pass made to a player who is in an offside position |\n", "| 3. | `Take On` | `3` | Attempted dribble past an opponent (excluding when qualifier 211 is present as this is ‘overrun’ and is not always a duel event) |\n", "| 4. | `Foul` | `4` | This event is shown when a foul is committed resulting in a free kick |\n", "| 5. | `Out` | `5` | Shown each time the ball goes out of play for a throw-in or goal kick |\n", "| 6. | `Corner Awarded` | `6` | Ball goes out of play for a corner kick |\n", "| 7. | `Tackle` | `7` | Tackle = dispossesses an opponent of the ball - Outcome 1 = win & retain possession or out of play, 0 = win tackle but not possession |\n", "| 8. | `Interception` | `8` | When a player intercepts any pass event between opposition players and prevents the ball reaching its target. Cannot be a clearance. |\n", "| 9. | `Turnover` | `9` | Unforced error / loss of possession - i.e. bad control of ball – NO LONGER USED (Replaced with Unsuccessful Touch + Overrun) |\n", "| 10. | `Save` | `10` | Goalkeeper event; saving a shot on goal. Can also be an outfield player event with qualifier 94 for blocked shot |\n", "| 11. | `Claim` | `11` | Goalkeeper event; catching a crossed ball |\n", "| 12. | `Clearance` | `12` | Player under pressure hits the ball clear of the defensive zone or/and out of play |\n", "| 13. | `MissedShots` or `Miss` | `13` | Any shot on goal which goes wide or over the goal |\n", "| 14. | `ShotOnPost` or `Post` | `14` | Whenever the ball hits the frame of the goal |\n", "| 15. | `SavedShot` or `Attempt Saved` | `15` | Shot saved - this event is for the player who made the shot. Qualifier 82 can be added for blocked shot. |\n", "| 16. | `Goal` | `16` | All goals |\n", "| 17. | `Card` | `17` | Bookings; will have red, yellow or 2nd yellow qualifier plus a reason |\n", "| 18. | `SubstitutionOff` or`Player off` | `18` | Player is substituted off |\n", "| 19. | `SubstitutionOn` or `Player on` | `19` | Player comes on as a substitute |\n", "| 20. | `Player retired` | `20` | Player is forced to leave the pitch due to injury and the team have no substitutions left |\n", "| 21. | `Player returns` | `21` | Player comes back on the pitch |\n", "| 22. | `Player becomes goalkeeper` | `22` | When an outfield player has to replace the goalkeeper |\n", "| 23. | `Goalkeeper becomes player` | `23` | If goalkeeper becomes an outfield player |\n", "| 24. | `Condition change` | `24` | Change in playing conditions |\n", "| 25. | `Official change` | `25` | Referee or linesman is replaced |\n", "| 26. | | `26` | |\n", "| 27. | `Start delay` | `27` | Used when there is a stoppage in play such as a player injury |\n", "| 28. | `End delay` | `28` | Used when the stoppage ends and play resumes |\n", "| 29. | | | |\n", "| 30. | `End` | `30` | End of a match period |\n", "| 31. | | | |\n", "| 32. | `Start` | `32` | Start of a match period |\n", "| 33. | | | |\n", "| 34. | `FormationSet` or `Team set up` | `34` | Team line up; qualifiers 30, 44, 59, 130, 131 will show player line up and formation |\n", "| 35. | `Player changed position` | `35` | Player moved to a different position but the team formation remained the same |\n", "| 36. | `Player changed Jersey number` | `36` | Player is forced to change jersey number, qualifier will show the new number |\n", "| 37. | `Collection End` | `37` | Event 30 signals end of half. This signals end of the match and thus data collection. |\n", "| 38. | `Temp_Goal` | `38` | Goal has occurred but it is pending additional detail qualifiers from Opta. Will change to event 16. |\n", "| 39. | `Temp_Attempt` | `39` | Shot on goal has occurred but is pending additional detail qualifiers from Opta. Will change to event 15. |\n", "| 40. | `FormationChange` or `Formation change` | `40` | Team alters its formation |\n", "| 41. | `Punch` | `41` | Goalkeeper event; ball is punched clear |\n", "| 42. | `GoodSkill` or `Good Skill` | `42` | A player shows a good piece of skill on the ball Ð such as a step over or turn on the ball Ð NO LONGER USED |\n", "| 43. | `Deleted event` | `43` | Event has been deleted Ð the event will remain as it was originally with the same ID but will be resent with the type altered to 43. |\n", "| 44. | `Aerial` | `44` | Aerial duel Ð 50/50 when the ball is in the air Ð outcome will represent whether the duel was won or lost |\n", "| 45. | `Challenge` | `45` | When a player fails to win the ball as an opponent successfully dribbles past them |\n", "| 46. | | | |\n", "| 47. | `Rescinded card` | `47` | This can occur post match if the referee rescinds a card he has awarded |\n", "| 48. | | `48` | |\n", "| 49. | `BallRecovery` or `Ball recovery` | `49` | Team wins the possession of the ball and successfully keeps possession for at least two passes or an attacking play |\n", "| 50. | `Dispossessed` | `50` | Player is successfully tackled and loses possession of the ball |\n", "| 51. | `Error` | `51` | Mistake by player losing the ball. Leads to a shot or goals as described with qualifier 169 or 170 |\n", "| 52. | `KeeperPickup` or `Keeper pick-up` | `52` | Goalkeeper event; picks up the ball |\n", "| 53. | `CrossNotClaimed` or `Cross not claimed` | `53` | Goalkeeper event; cross not successfully caught |\n", "| 54. | `Smother` | `54` | Goalkeeper event; comes out and covers the ball in the box winning possession |\n", "| 55. | `OffsideProvoked` or `Offside provoked` | `55` | Awarded to last defender when an offside decision is given against an attacker |\n", "| 56. | `ShieldBallOpp` or `Shield ball opp` | `56` | Defender uses his body to shield the ball from an opponent as it rolls out of play |\n", "| 57. | `Foul throw-in` | `57` | A throw-in not taken correctly resulting in the throw being awarded to the opposing team |\n", "| 58. | `PenaltyFaced` or `Penalty faced` | `58` | Goalkeeper event; penalty by opposition team |\n", "| 59. | `KeeperSweeper` or `Keeper Sweeper` | `59` | When keeper comes off his line and/or out of his box to clear the ball |\n", "| 60. | `ChanceMissed` or `Chance missed` | `60` | Used when a player does not actually make a shot on goal but was in a good position to score and on`ly just missed receiving a pass |\n", "| 61. | `BallTouch` or `Ball touch` | `61 | Used when a player makes a bad touch on the ball and loses possession. Outcome 1 Ð ball simply hit the player unintentionally. Outcome 0 Ð Player unsuccessfully controlled the ball. |\n", "| 62. | | | |\n", "| 63. | `Temp_Save` | `63` | An event indicating a save has occurred but without full details. Event 10 will follow shortly afterwards with full details. |\n", "| 64. | `Resume` | `64` | Match resumes on a new date after being abandoned mid game. |\n", "| 65. | `Contentious referee decision` | `65` | Any major talking point or error made by the referee Ð decision will be assigned to the relevant team |\n", "| 66. | `Possession Data` | `66` | Possession event will appear every 5 mins |\n", "| 67. | `50/50` | `67` | \tNew duel - 2 players running for a loose ball - GERMAN ONLY. Outcome 1 or 0. |\n", "| 68. | `Referee Drop Ball` | `68` | Delay - ref stops - this to event given to both teams on restart. No Outcome |\n", "| 69. | `Failed to Block` | `69` | New duel (put through-Q266 is the winning duel event). Attempt to block a shot or pass - challenge lost |\n", "| 70. | `Injury Time Announcement` | `70` | Injury Time awarded by Referee |\n", "| 71. | `Coach Setup` | `71` | Coach Type; 1,2,18,30,32,54,57,58,59 |\n", "| 72. | `Caught Offside` | `72` | \tNew event to just show player who is offside instead of offside pass event |\n", "| 73. | `Other Ball Contact` | `73` | This is an automated extra event for DFL. It comes with a tackle or an interception and indicates if the player who made the tackle/interception retained the ball after this action or if the tackle/interception was a single ball touch (other ball contact with type “interception”, type “Defensive Clearance” or type “ TackleRetainedBall). |\n", "| 74. | `Blocked Pass` | `74` | Defender is close to player in possession and blocks a pass. Different from interception which is where the player has moved to intercept. |\n", "| 75. | `Delayed Start` | `75` | Match start delayed |\n", "| 76. | `Early end` | `76` | The match has had an early end |\n", "| 77. | `Player Off Pitch` | `77` | Event indicating that a player is now off the pitch |\n", "| 80. | `Unknown` | `80` | |\n", "| 83. | `Unknown` | `83` | |" ] }, { "cell_type": "code", "execution_count": 26, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([34, 32, 1, 49, 5, 61, 4, 12, 6, 13, 44, 43, 74, 52, 7, 55, 2,\n", " 10, 15, 3, 45, 8, 50, 27, 28, 17, 16, 51, 11, 42, 30, 14, 18, 19,\n", " 37, 80, 83, 67, 24])" ] }, "execution_count": 26, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_cry_lei_events['type_id'].unique()" ] }, { "cell_type": "code", "execution_count": 27, "metadata": {}, "outputs": [], "source": [ "# Define function to \n", "def clean_event_names(df):\n", " \n", " \"\"\"\n", " Function to...\n", " \"\"\"\n", " \n", " ## Read in the reference dataset of Event Types as a pandas DataFrame\n", " df_event_types_ref = pd.read_csv(os.path.join(data_dir_opta, 'reference', 'opta_event_types.csv'))\n", "\n", "\n", " ## Prepare DataFrame to create dictionary\n", "\n", " ### Remove Null values\n", " df_event_types_ref = df_event_types_ref[df_event_types_ref['eventTypeId'].notna()]\n", "\n", " ### Convert data types\n", " df_event_types_ref['eventTypeId'] = df_event_types_ref['eventTypeId'].astype(int)\n", " #df_event_types_ref['eventTypeId'] = 'isEventType_' + df_event_types_ref['eventTypeId'].astype(str)\n", "\n", " ### \n", " df_event_types_ref['eventTypeName'] = df_event_types_ref['eventTypeName'].str.title().str.replace(' ', '').str.replace('/', '').str.replace('-', '')\n", " df_event_types_ref['eventTypeName'] = 'is' + df_event_types_ref['eventTypeName'].astype(str)\n", "\n", "\n", " ## Create a dictionary of Event IDs and Event Names from the reference dataset\n", " dict_event_types = dict(zip(df_event_types_ref['eventTypeId'], df_event_types_ref['eventTypeName']))\n", " \n", " \n", " ## Map Event Names to Type IDs\n", " df['event_name'] = df['type_id'].map(dict_event_types)\n", " \n", " \n", " ## Return DataFrame\n", " return df" ] }, { "cell_type": "code", "execution_count": 28, "metadata": {}, "outputs": [], "source": [ "# Apply Clean Event Types column function\n", "df_cry_lei_events = clean_event_names(df_cry_lei_events)\n", "df_cry_bri_events = clean_event_names(df_cry_bri_events)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now that the Event Types column has been cleaned, the next stage is to clean up the Qualifier types." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "\n", "### 4.05. Clean Qualifier Types Columns\n", "There are 229 different qualifiers with the following Ids and definitions (see the Opta F24 Appendices document [[link](https://github.com/eddwebster/football_analytics/blob/master/docs/opta/f24_appendices.docx)]). Also see the definitions on the Stats Perform website [[link](https://www.statsperform.com/opta-event-definitions/)])\n", "\n", "**Note:** these Qualifier Types are not to be confused with the 219 Satisified Event Types (see below), that are available in the JSON string extracted from [WhoScored!](https://www.whoscored.com/).\n", "\n", "**Note:** there are 19 qualifier types missing from the definitions list as they are not observed in the event data. The IDs of these Events are: 27, 43, 52, 58, 98, 99, 104, 105, 125, 126, 129, 142, 143, 148, 149, 150, 151, 152, 193.\n", "\n", "\n", "| No. | `qualifierTypeName` | `qualifierTypeId` | Values | Definition | Qualifier Category | Associated Event Type (`typeName`) |\n", "|----------|-----------------------------------|-----------------------|-------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------|-----------------------------------------|\n", "| 1. | `Long ball` | `1` | | Long pass over 35 yards | Pass Events | 1 |\n", "| 2. | `Cross` | `2` | | A ball played in from wide areas into the box | Pass Events | 1 |\n", "| 3. | `Head pass` | `3` | | Pass made with a players head | Pass Events | 1 |\n", "| 4. | `Through ball` | `4` | | Ball played through for player making an attacking run to create a chance on goal | Pass Events | 1 |\n", "| 5. | `Free kick taken` | `5` | | Any free kick; direct or indirect | Pass Events | 1 |\n", "| 6. | `Corner taken` | `6` | | All corners. Look for qualifier 6 but excluding qualifier 2 for short corners | Pass Events | 1 |\n", "| 7. | `Players caught offside` | `7` | Player ID | Player who was in an offside position when pass was made. | Pass Events | 1 |\n", "| 8. | `Goal disallowed` | `8` | | Pass led to a goal disallowed for a foul or offside | Pass Events | 1 |\n", "| 9. | `Penalty` | `9` | | When attempt on goal was a penalty kick. ALSO used on Event type 4 to indicate a penalty was awarded | Shot Descriptors | 13, 14, 15, 16 |\n", "| 10. | `Hand` | `10` | | Handball | Foul & Card Events | 4 |\n", "| 11. | `6-seconds violation` | `11` | | Goalkeeper held onto the ball longer than 6 seconds resulting in a free kick | Foul & Card Events | 4 |\n", "| 12. | `Dangerous play` | `12` | | A foul due to dangerous play | Foul & Card Events | 4 |\n", "| 13. | `Foul` | `13` | | All fouls | Foul & Card Events | 4 |\n", "| 14. | `Last line` | `14` | | When a player makes a defensive action and they are the last person between the opponent and the goal | Defensive Events | |\n", "| 15. | `Head` | `15` | | Any event where the player used their head such as a shot or a clearance | Body Part | |\n", "| 16. | `Small box-centre` | `16` | | Zone of the pitch - See appendix 7 | Shot Location Descriptors | |\n", "| 17. | `Box-centre` | `17` | | Zone of the pitch - See appendix 7 | Shot Location Descriptors | |\n", "| 18. | `Out of box-centre` | `18` | | Zone of the pitch - See appendix 7 | Shot Location Descriptors | |\n", "| 19. | `35+ centre` | `19` | | Zone of the pitch - See appendix 7 | Shot Location Descriptors | |\n", "| 20. | `Right footed` | `20` | | Player shot with right footed | Body Part | |\n", "| 21. | `Other body part` | `21` | | Shot was neither via a player’s head or foot for example knee or chest | Body Part | |\n", "| 22. | `Regular play` | `22` | | Shot during open play as opposed to from a set play | Pattern of Play | 13, 14, 15, 16 |\n", "| 23. | `Fast break` | `23` | | Shot occurred following a fast break situation | Pattern of Play | 13, 14, 15, 16 |\n", "| 24. | `Set piece` | `24` | | Shot occurred from a crossed free kick | Pattern of Play | 13, 14, 15, 16 |\n", "| 25. | `From corner` | `25` | | Shot occurred from a corner | Pattern of Play | 13, 14, 15, 16 |\n", "| 26. | `Free kick` | `26` | | Shot occurred directly from a free kick | Pattern of Play | 13, 14, 15, 16 |\n", "| 27. | | | | | | |\n", "| 28. | `own goal` | `28` | | Own goal. Note: Use the inverse coordinates of the goal location | Shot Descriptors | 13, 14, 15, 16 |\n", "| 29. | `Assisted` | `29` | | Indicates that there was a pass (assist) from another player to set up the goal opportunity | Line Up / Subs / Formation | 13, 14, 15, 16 |\n", "| 30. | `Involved` | `30` | | Player ID's in line up | Foul & Card Events | 32, 34, 35, 36, 40 |\n", "| 31. | `Yellow Card` | `31` | | Player shown a yellow card | Foul & Card Events | |\n", "| 32. | `Second yellow` | `32` | | Player receives a 2nd yellow card which automatically results in a red card | Foul & Card Events | |\n", "| 33. | `Red Card` | `33` | | Player shown a straight red card | Foul & Card Events | |\n", "| 34. | `Referee abuse` | `34` | | Card shown to player because of abuse to the referee | Foul & Card Events | 4 |\n", "| 35. | `Argument` | `35` | | Card shown to player because of an argument | Foul & Card Events | 4 |\n", "| 36. | `Fight` | `36` | | Card shown to player because of their involvement in a fight | Foul & Card Events | 4 |\n", "| 37. | `Time wasting` | `37` | | Card shown to player for time wasting | Foul & Card Events | 4 |\n", "| 38. | `Excessive celebration` | `38` | | Card shown to player for excessively celebrating a goal | Foul & Card Events | 4 |\n", "| 39. | `Crowd interaction` | `39` | | Card shown to player because of contact or communication with the crowd | Foul & Card Events | 4 |\n", "| 40. | `Other reason` | `40` | | Card shown for unknown reason | Foul & Card Events | 4 |\n", "| 41. | `Injury` | `41` | | Substitution, event 18, because of injury | Line Up / Subs / Formation | 32, 34, 35, 36, 40 |\n", "| 42. | `Tactical` | `42` | | Substitution, event 18 for tactical reasons | Line Up / Subs / Formation | 32, 34, 35, 36, 40 |\n", "| 43. | | | | | | |\n", "| 44. | `Player Position` | `44` | Dynamic | Goalkeeper, Defender, Midfielder, Forward or Substitute. These are the default / natural positions associated with each player and not necessarily the position they played in the match; see qualifier 131 for this. | Line Up / Subs / Formation | 32, 34, 35, 36, 40 |\n", "| 45. | `Temperature` | `45` | | ... | ... | |\n", "| 46. | `Conditions` | `46` | | ... | ... | |\n", "| 47. | `Field Pitch` | `47` | | ... | ... | |\n", "| 48. | `Lightings` | `48` | | ... | ... | |\n", "| 49. | `Attendance figure` | `49` | Dynamic | Number of people in the crowd | Attendance | |\n", "| 50. | `Official position` | `50` | 1, 2, 3, 4 | Referee, Linesman#1, Linesman#2, Forth official | Referee | |\n", "| 51. | `Official Id` | `51` | Official ID | Unique ID for the official | Referee | |\n", "| 52. | | | | | | |\n", "| 53. | `Injured player id` | `53` | ID of player injured | ID of the player who is injured and causing a delay in the game | Stoppages | 27 |\n", "| 54. | `End cause` | `54` | 1,2,3,4,5,6,7,99,100 | Golden goal, weather, crowd, insufficient players, floodlight failure, frozen pitch, waterlogged pitch, other, unknown | General | |\n", "| 55. | `Related event ID` | `55` | Event_id | This will appear for goals or shots, the related event_id will be that of the assist and thus show the assisting player ID | Pattern of Play | 13, 14, 15, 16 |\n", "| 56. | `Zone` | `56` | Back, left, centre, right | Area on the pitch - see appendix 7 | General | |\n", "| 57. | `End type` | `57` | End of the match | This will be shown for substitutions, line ups, line up changes | General | |\n", "| 58. | | | | | | |\n", "| 59. | `Jersey Number` | `59` | Shirt number of player(s) | This will be shown for substitutions, line ups, line up changes | Line Up / Subs / Formation | 32, 34, 35, 36, 40 |\n", "| 60. | `Small box-right` | `60` | | Zone of the pitch - See appendix 7 | Shot Location Descriptors | |\n", "| 61. | `Small box-left` | `61` | | Zone of the pitch - See appendix 7 | Shot Location Descriptors | |\n", "| 62. | `Box-deep right` | `62` | | Zone of the pitch - See appendix 7 | Shot Location Descriptors | |\n", "| 63. | `Box-right` | `63` | | Zone of the pitch - See appendix 7 | Shot Location Descriptors | |\n", "| 64. | `Box-left` | `64` | | Zone of the pitch - See appendix 7 | Shot Location Descriptors | |\n", "| 65. | `Box-deep left` | `65` | | Zone of the pitch - See appendix 7 | Shot Location Descriptors | |\n", "| 66. | `Out of box-deep right` | `66` | | Zone of the pitch - See appendix 7 | Shot Location Descriptors | |\n", "| 67. | `Out of box-right` | `67` | | Zone of the pitch - See appendix 7 | Shot Location Descriptors | |\n", "| 68. | `Out of box-left` | `68` | | Zone of the pitch - See appendix 7 | Shot Location Descriptors | |\n", "| 69. | `Out of box-deep left` | `69` | | Zone of the pitch - See appendix 7 | Shot Location Descriptors | |\n", "| 70. | `35+ right` | `70` | | Zone of the pitch - See appendix 7 | Shot Location Descriptors | |\n", "| 71. | `35+ left` | `71` | | Zone of the pitch - See appendix 7 | Shot Location Descriptors | |\n", "| 72. | `Left footed` | `72` | | Player shot with their left foot | Body Part | |\n", "| 73. | `Left` | `73` | | Hit the left post or missed left | Shot Location Descriptors | |\n", "| 74. | `High` | `74` | | Hit crossbar or missed over | Shot Location Descriptors | |\n", "| 75. | `Right` | `75` | | Hit right post or missed right | Shot Location Descriptors | |\n", "| 76. | `Low Left` | `76` | | Zone of the goalmouth - See appendix 6 | Shot Location Descriptors | |\n", "| 77. | `High Left` | `77` | | Zone of the goalmouth - See appendix 6 | Shot Location Descriptors | |\n", "| 78. | `Low Centre` | `78` | | Zone of the goalmouth - See appendix 6 | Shot Location Descriptors | |\n", "| 79. | `High Centre` | `79` | | Zone of the goalmouth - See appendix 6 | Shot Location Descriptors | |\n", "| 80. | `Low Right` | `80` | | Zone of the goalmouth - See appendix 6 | Shot Location Descriptors | |\n", "| 81. | `High Right` | `81` | | Zone of the goalmouth - See appendix 6 | Shot Location Descriptors | |\n", "| 82. | `Blocked` | `82` | | Zone of the goalmouth - See appendix 6 | Shot Location Descriptors | |\n", "| 83. | `Close Left` | `83` | | Zone of the goalmouth - See appendix 6 | Shot Location Descriptors | |\n", "| 84. | `Close Right` | `84` | | Zone of the goalmouth - See appendix 6 | Shot Location Descriptors | |\n", "| 85. | `Close High` | `85` | | Zone of the goalmouth - See appendix 6 | Shot Location Descriptors | |\n", "| 86. | `Close Left and High` | `86` | | Zone of the goalmouth - See appendix 6 | Shot Location Descriptors | |\n", "| 87. | `Close Right and High` | `87` | | Zone of the goalmouth - See appendix 6 | Shot Location Descriptors | |\n", "| 88. | `High claim` | `88` | | Event 11 Claim - Goalkeeper claims possession of a crossed ball | Goalkeeper Events | 10, 11, 12 |\n", "| 89. | `1 on 1` | `89` | | Event 10 Save; when attacker was clear with no defenders between him and the goalkeeper | Goalkeeper Events | 10, 11, 12 |\n", "| 90. | `Deflected save` | `90` | | Event 10 Save; when goalkeeper saves a shot but does not catch the ball | Goalkeeper Events | 10, 11, 12 |\n", "| 91. | `Dive and deflect` | `91` | | Event 10 Save; when goalkeeper saves a shot while diving but does not catch the ball | Goalkeeper Events | 10, 11, 12 |\n", "| 92. | `Catch` | `92` | | Event 10 Save; when goalkeeper saves a shot and catches it | Goalkeeper Events | 10, 11, 12 |\n", "| 93. | `Dive and catch` | `93` | | Event 10 Save; when goalkeeper saves a shot while diving and catches it | Goalkeeper Events | 10, 11, 12 |\n", "| 94. | `Def block` | `94` | | Defender blocks an opposition shot. Shown with event 10. | Defensive Events | |\n", "| 95. | `Back pass` | `95` | | Free kick given for an illegal pass to the goalkeeper which was collected by his hands or picked up | Foul & Card Events | 4 |\n", "| 96. | `Corner situation` | `96` | | Pass or shot event in corner situation. 25 is used when the goal is direct from corner, 96 relates to 2nd phase attack. | Pattern of Play | 13, 14, 15, 16 |\n", "| 97. | `Direct free` | `97` | | 26 will be used for shot directly from a free kick. 97 only used with Opta GoalData (game system 4) but not with full data. | Pattern of Play | 13, 14, 15, 16 |\n", "| 98. | | | | | | |\n", "| 99. | | | | | | |\n", "| 100. | `Six Yard Blocked` | `100` | | Shot blocked on the 6 yard line | Shot Location Descriptors | |\n", "| 101. | `Saved Off Line` | `101` | | Shot saved on the goal line | Shot Location Descriptors | |\n", "| 102. | `Goal Mouth Y Coordinate` | `102` | 0-100 | Y Co-ordinate of where a shot crossed goal line - see Appendix 4 | Shot Location Descriptors | |\n", "| 103. | `Goal Mouth Z Coordinate` | `103` | 0-100 | Z Co-ordinate for height at which a shot crossed the goal line - see Appendix 4 | Shot Location Descriptors | |\n", "| 104. | | | | | | |\n", "| 105. | | | | | | |\n", "| 106. | `Attacking Pass` | `106` | | A pass in the opposition’s half of the pitch | Pass Events | 1 |\n", "| 107. | `Throw In` | `107` | | Throw-in taken | Pass Events | 1 |\n", "| 108. | `Volley` | `108` | | | ... | |\n", "| 109. | `Overhead` | `109` | | | ... | |\n", "| 110. | `Half Volley` | `110` | | | ... | |\n", "| 111. | `Diving Header` | `111` | | | ... | |\n", "| 112. | `Scramble` | `112` | | Goal where there was a scramble for possession of the ball and the defence had an opportunity to clear | Pattern of Play | 13, 14, 15, 16 |\n", "| 113. | `Strong` | `113` | | Shot was subjectively classed as strong | Shot Descriptors | 13, 14, 15, 16 |\n", "| 114. | `Weak` | `114` | | Shot was subjectively classed as weak | Shot Descriptors | 13, 14, 15, 16 |\n", "| 115. | `Rising` | `115` | | Shot was rising in the air | Shot Descriptors | 13, 14, 15, 16 |\n", "| 116. | `Dipping` | `116` | | Shot was dipping towards the ground | Shot Descriptors | 13, 14, 15, 16 |\n", "| 117. | `Lob` | `117` | | Shot was an attempt by the attacker to play the ball over the goalkeeper and into the goal | Shot Descriptors | 13, 14, 15, 16 |\n", "| 118. | `One Bounce` | `118` | | | Shot Descriptors | 13, 14, 15, 16 |\n", "| 119. | `Few Bounces` | `119` | | | Shot Descriptors | 13, 14, 15, 16 |\n", "| 120. | `Swerve Left` | `120` | | Shot which swerves to the left - from attackers perspective | Shot Descriptors | 13, 14, 15, 16 |\n", "| 121. | `Swerve Right` | `121` | | Shot which swerves to the right - from attackers perspective | Shot Descriptors | 13, 14, 15, 16 |\n", "| 122. | `Swerve Moving` | `122` | | Shot which swerves in several directions | Shot Descriptors | 13, 14, 15, 16 |\n", "| 123. | `Keeper Throw` | `123` | | Pass event - goalkeeper throws the ball out | Goalkeeper Events | 10, 11, 12 |\n", "| 124. | `Goal Kick` | `124` | | Pass event – goal kick | Goalkeeper Events | 10, 11, 12 |\n", "| 125. | | | | | | |\n", "| 126. | | | | | | |\n", "| 127. | `Direction of play` | `127` | Right to Left | Event type 32 - Actual direction of play in relation to TV camera. X/Y coordinates however are ALWAYS all normalized to Left to Right. | General | |\n", "| 128. | `Punch` | `128` | | Clearance by goalkeeper where he punches the ball clear | Goalkeeper Events | 10, 11, 12 |\n", "| 129. | | | | | | |\n", "| 130. | `Team Formation` | `130` | Formation ID | See appendix 8 | Line Up / Subs / Formation | 32, 34, 35, 36, 40 |\n", "| 131. | `Team Player Formation` | `131` | 1 to 11 | Player position within a formation - 'See appendix 8 | Line Up / Subs / Formation | 32, 34, 35, 36, 40 |\n", "| 132. | `Dive` | `132` | | Free kick or card event; player penalised for simulation | Foul & Card Events | 4 |\n", "| 133. | `Deflection` | `133` | | Shot deflected off another player | Shot Descriptors | 13, 14, 15, 16 |\n", "| 134. | `Far Wide Left` | `134` | | | ... | |\n", "| 135. | `Far Wide Right` | `135` | | | ... | |\n", "| 136. | `Keeper Touched` | `136` | | Goal where the goalkeeper got a touch on the ball as it went in | Shot Descriptors | 13, 14, 15, 16 |\n", "| 137. | `Keeper Saved` | `137` | | Shot going wide or over the goal but still collected/saved by the goalkeeper with event type 15 | Shot Descriptors | 13, 14, 15, 16 |\n", "| 138. | `Hit Woodwork` | `138` | | Any shot which hits the post or crossbar | Shot Descriptors | 13, 14, 15, 16 |\n", "| 139. | `Own Player` | `139` | | Shot saved by goalkeeper that was deflected by a defender | Goalkeeper Events | 13, 14, 15, 16 |\n", "| 140. | `Pass End X` | `140` | 0-100 | The x pitch coordinate for the end point of a pass - See Appendix 5 | Pass Events | 1 |\n", "| 141. | `Pass End Y` | `141` | 0-100 | The y pitch coordinate for the end point of a pass - See Appendix 5 | Pass Events | 1 |\n", "| 142. | | | | | | |\n", "| 143. | | | | | | |\n", "| 144. | `Deleted Event Type` | `144` | Event ID | An event which should be removed. Value will show the ID of this event | General | |\n", "| 145. | `Formation slot` | `145` | 1 to 11 | Formation position of a player coming on - see appendix 8 | Line Up / Subs / Formation | 32, 34, 35, 36, 40 |\n", "| 146. | `Blocked X Coordinate` | `146` | 0-100 | The x pitch coordinate for where a shot was blocked | Shot Location Descriptors | |\n", "| 147. | `Blocked Y Coordinate` | `147` | 0-100 | The y pitch coordinate for where a shot was blocked | Shot Location Descriptors | |\n", "| 148. | | | | | | |\n", "| 149. | | | | | | |\n", "| 150. | | | | | | |\n", "| 151. | | | | | | |\n", "| 152. | | | | | | |\n", "| 153. | `Not past goal line` | `153` | | Shot missed which does not pass the goal line | Shot Descriptors | 13, 14, 15, 16 |\n", "| 154. | `Intentional Assist` | `154` | | Shot from an intentional assist i.e. The assisting player intended the pass, no deflection etc | Pattern of Play | 13, 14, 15, 16 |\n", "| 155. | `Chipped` | `155` | | Pass which was chipped into the air | Pass Events | 1 |\n", "| 156. | `Lay-off` | `156` | | Pass where player laid the ball into the path of a teammates run | Pass Events | 1 |\n", "| 157. | `Launch` | `157` | | Pass played from a player’s own half up towards front players. Aimed to hit a zone rather than a specific player | Pass Events | 1 |\n", "| 158. | `Persistent Infringement` | `158` | | Card shown to player for persistent fouls | Foul & Card Events | 4 |\n", "| 159. | `Foul and Abusive Language` | `159` | | Card shown for player using foul language | Foul & Card Events | 4 |\n", "| 160. | `Throw In set piece` | `160` | | Shot came from a throw-in set piece | Pattern of Play | 13, 14, 15, 16 |\n", "| 161. | `Encroachment` | `161` | | Card shown for player who moves within 10 yards of an opponent’s free kick | Foul & Card Events | 4 |\n", "| 162. | `Leaving field` | `162` | | Card shown for player leaving the field without permission | Foul & Card Events | 4 |\n", "| 163. | `Entering field` | `163` | | Card shown for player entering the field during play without referee's permission | Foul & Card Events | 4 |\n", "| 164. | `Spitting` | `164` | | Card shown for spitting | Foul & Card Events | 4 |\n", "| 165. | `Professional foul` | `165` | | Card shown for a deliberate tactical foul | Foul & Card Events | 4 |\n", "| 166. | `Handling on the line` | `166` | | Card shown to an outfield player for using their hand to keep the ball out of the goal | Foul & Card Events | 4 |\n", "| 167. | `Out of play` | `167` | | Tackle or clearance event sent the ball out of play | Defensive Events | |\n", "| 168. | `Flick-on` | `168` | | Pass where a player has \"flicked\" the ball forward using their head | Pass Events | 1 |\n", "| 169. | `Leading to attempt` | `169` | | A player error, event 51, which leads to an opponent shot on goal | Defensive Events | |\n", "| 170. | `Leading to goal` | `170` | | A player error, event 51, which lead to an opponent scoring a goal | Defensive Events | |\n", "| 171. | `Rescinded Card` | `171` | | Referee rescind a card post match | Foul & Card Events | 4 |\n", "| 172. | `No impact on timing` | `172` | | Player booked on bench but who hasn't played any minutes in the match | Foul & Card Events | 4 |\n", "| 173. | `Parried safe` | `173` | | Goalkeeper save where shot is parried to safety | Goalkeeper Events | 10, 11, 12 |\n", "| 174. | `Parried danger` | `174` | | Goalkeeper save where shot is parried but only to another opponent | Goalkeeper Events | 10, 11, 12 |\n", "| 175. | `Fingertip` | `175` | | Goalkeeper save using his fingertips | Goalkeeper Events | 10, 11, 12 |\n", "| 176. | `Caught` | `176` | | Goalkeeper catches the ball | Goalkeeper Events | 10, 11, 12 |\n", "| 177. | `Collected` | `177` | | Goalkeeper save and collects possession of the ball | Goalkeeper Events | 10, 11, 12 |\n", "| 178. | `Standing` | `178` | | Goalkeeper save while standing | Goalkeeper Events | 10, 11, 12 |\n", "| 179. | `Diving` | `179` | | Goalkeeper save while diving | Goalkeeper Events | 10, 11, 12 |\n", "| 180. | `Stooping` | `180` | | Goalkeeper saves while stooping | Goalkeeper Events | 10, 11, 12 |\n", "| 181. | `Reaching` | `181` | | Goalkeeper save where goalkeeper reaches for the ball | Goalkeeper Events | 10, 11, 12 |\n", "| 182. | `Hands` | `182` | | Goalkeeper saves with his hands | Goalkeeper Events | 10, 11, 12 |\n", "| 183. | `Feet` | `183` | | Goalkeeper save using his feet | Goalkeeper Events | 10, 11, 12 |\n", "| 184. | `Dissent` | `184` | | Cad shown when a player does not obey referee instructions | Foul & Card Events | 4 |\n", "| 185. | `Blocked cross` | `185` | | Clearance; cross is blocked | Defensive Events | |\n", "| 186. | `Scored` | `186` | | Goalkeeper event - shots faced and not saved resulting in goal | Goalkeeper Events | 10, 11, 12 |\n", "| 187. | `Saved` | `187` | | Goalkeeper event - shots faced and saved | Goalkeeper Events | 10, 11, 12 |\n", "| 188. | `Missed` | `188` | | Goalkeeper event - shot faced which went wide or over. Did not require a save. | Goalkeeper Events | 10, 11, 12 |\n", "| 189. | `Player Not Visible` | `189` | | Broadcast footage showing replay and not live footage – this event is what Opta analysts believe occurred. | General | |\n", "| 190. | `From shot off target` | `190` | | Used with Event 10. Indicates a shot was saved by the goalkeeper but in fact the shot was going wide and not on target | Goalkeeper Events | 10, 11, 12 |\n", "| 191. | `Off the ball foul` | `191` | | Foul committed by and on a player who is not in possession of the ball | Foul & Card Events | 4 |\n", "| 192. | `Block by hand` | `192` | | Outfield player blocks a shot with their hand | Foul & Card Events | 4 |\n", "| 193. | | | | | | |\n", "| 194. | `Captain` | `194` | Player ID | ID of the player who is the team captain | Line Up / Subs / Formation | 32, 34, 35, 36, 40 |\n", "| 195. | `Pull Back` | `195` | | Player in opposition’s penalty box reaches the by-line and passes (cuts) the ball backwards to a teammate | Pass Events | 1 |\n", "| 196. | `Switch of play` | `196` | | Any pass which crosses the centre zone of the pitch and in length is greater than 60 on the y axis of the pitch | Pass Events | 1 |\n", "| 197. | `Team kit` | `197` | Kit ID | Kit of the team | Line Up / Subs / Formation | 32, 34, 35, 36, 40 |\n", "| 198. | `GK hoof` | `198` | | Goalkeeper drops the ball on the ground and kicks it long towards a position rather than a specific player | Goalkeeper Events | 10, 11, 12 |\n", "| 199. | `Gk kick from hands` | `199` | | Goalkeeper kicks the ball forward straight out of his hands | Goalkeeper Events | 10, 11, 12 |\n", "| 200. | `Referee stop` | `200` | | Referee stops play | Referee | |\n", "| 201. | `Referee delay` | `201` | | Delay in play instructed by referee | Referee | |\n", "| 202. | `Weather problem` | `202` | | Bad weather stops or interrupts play | Stoppages | 27 |\n", "| 203. | `Crowd trouble` | `203` | | Trouble within the crowd stops or delays play | Stoppages | 27 |\n", "| 204. | `Fire` | `204` | | Fire with the stadium stops or delays play | Stoppages | 27 |\n", "| 205. | `Object thrown on pitch` | `205` | | Object throw from the crowd lands on the pitch and delays play | Stoppages | 27 |\n", "| 206. | `Spectator on pitch` | `206` | | Spectator comes onto the pitch and forces a delay in play | Stoppages | 27 |\n", "| 207. | `Awaiting officials decision` | `207` | | Given to an event/delay where the referee still has to make a decision | Stoppages | 27 |\n", "| 208. | `Referee Injury` | `208` | | Referee sustained injury causing stoppage in play | Referee / Stoppages | 27 |\n", "| 209. | `Game end` | `209` | | The game is finished | General | |\n", "| 210. | `Assist` | `210` | | The pass was an assist for a shot. The type of shot then dictates whether it was a goal assist or just key pass. | Pass Events | 1 |\n", "| 211. | `Overrun` | `211` | | TAKE ON (3) – where a player takes on an opponent but the ball runs away from them out of play or to an opponent. | General | |\n", "| 212. | `Length` | `212` | Dynamic - yards of pitch | The estimated length the ball has travelled during the associated event. | Pass Events | 1 |\n", "| 213. | `Angle` | `213` | 0 to 6.28 (Radians) | The angle the ball travels at during an event relative to the direction of play. Shown in radians. | Pass Events | 1 |\n", "| 214. | `Big Chance` | `214` | | Shot was deemed by Opta analysts an excellent opportunity to score – clear cut chance eg one on one | Shot Descriptors | 13, 14, 15, 16 |\n", "| 215. | `Individual Play` | `215` | | Player created the chance to shoot by himself, not assisted. For example he dribbled to create space for himself and shot. | Shot Descriptors | 13, 14, 15, 16 |\n", "| 216. | `2nd related event ID` | `216` | Event_id | If there was a 2nd assist, i.e a pass to create the opportunity for the player making the assist. MLS and German Bundesliga 1 & 2. | Pattern of Play | 13, 14, 15, 16 |\n", "| 217. | `2nd assited` | `217` | | Indicates that this shot had a significant pass to create the opportunity for the pass which led to a goal | Shot Descriptors | 13, 14, 15, 16 |\n", "| 218. | `2nd assist` | `218` | | Pass was deemed a 2nd assist - created the opportunity for another player to assist a goal | Pass Events | 1 |\n", "| 219. | `Players on both posts` | `219` | | Assigned to event 6 indicating there were defensive players on both posts when a corner was taken | Pass Events | 1 |\n", "| 220. | `Player on near post` | `220` | | Assigned to event 6 indicating there was a defensive player on only the near post when a corner was taken | Pass Events | 1 |\n", "| 221. | `Player on far post` | `221` | | Assigned to event 6 indicating there was a defensive player on only the far post when corner was taken | Pass Events | 1 |\n", "| 222. | `No players on posts` | `222` | | Assigned to event 6 indicating there were no defensive players on either post when a corner was taken | Pass Events | 1 |\n", "| 223. | `Inswinger` | `223` | | Corner was crossed into the box swerving towards the goal | Pass Events | 1 |\n", "| 224. | `Outswinger` | `224` | | Corner was crossed into the box swerving away from the goal | Pass Events | 1 |\n", "| 225. | `Straight` | `225` | | Corner was crossed into the box with a straight ball flight | Pass Events | 1 |\n", "| 226. | `Suspended` | `226` | | Game is has not finished but is suspended | Stoppages | 27 |\n", "| 227. | `Resume` | `227` | | Game has resumed after being suspended mid-way through on a previous date | Stoppages | 27 |\n", "| 228. | `Own shot blocked` | `228` | | Player blocks an attacking shot unintentionally from their teammate | Shot Descriptors | 13, 14, 15, 16 |\n", "| 229. | `Post match complete` | `229` | | Opta post match quality control has been completed on this match | General | |" ] }, { "cell_type": "code", "execution_count": 29, "metadata": {}, "outputs": [], "source": [ "# Define function to \n", "def clean_qualifier_names(df):\n", " \n", " \"\"\"\n", " Function to...\n", " \"\"\"\n", " \n", " ## Read in the reference dataset of Event Types as a pandas DataFrame\n", " df_qualifier_types_ref = pd.read_csv(os.path.join(data_dir_opta, 'reference', 'opta_qualifier_types.csv'))\n", "\n", "\n", " ## Prepare DataFrame to create dictionary\n", "\n", " ### Remove Null values\n", " df_qualifier_types_ref = df_qualifier_types_ref[df_qualifier_types_ref['qualifierTypeId'].notna()]\n", "\n", " ### Convert data types\n", " df_qualifier_types_ref['qualifierTypeId'] = df_qualifier_types_ref['qualifierTypeId'].astype(int)\n", " df_qualifier_types_ref['qualifierTypeId'] = df_qualifier_types_ref['qualifierTypeId'].astype(str)\n", "\n", " ### \n", " df_qualifier_types_ref['qualifierTypeName'] = df_qualifier_types_ref['qualifierTypeName'].str.title().str.replace(' ', '').str.replace('/', '').str.replace('-', '')\n", " df_qualifier_types_ref['qualifierTypeName'] = 'is' + df_qualifier_types_ref['qualifierTypeName'].astype(str)\n", "\n", "\n", " ## Create a dictionary of Qualifier IDs and Qualifier Names from the reference dataset\n", " dict_qualifier_types = dict(zip(df_qualifier_types_ref['qualifierTypeId'], df_qualifier_types_ref['qualifierTypeName']))\n", "\n", "\n", " ## Map Qualifier Names to Qualifier IDs\n", " df = df.rename(columns=dict_qualifier_types)\n", " \n", " \n", " ## Drop Unknown columns (Qualifier Types 345-458)\n", " df.drop(['isUnknown'], axis=1, inplace=True)\n", " \n", " ## Return DataFrame\n", " return df" ] }, { "cell_type": "code", "execution_count": 30, "metadata": {}, "outputs": [], "source": [ "# Apply Clean Qualifier ID columns function\n", "df_cry_lei_events = clean_qualifier_names(df_cry_lei_events)\n", "df_cry_bri_events = clean_qualifier_names(df_cry_bri_events)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "\n", "### 4.06. Rename Columns\n", "Some columns require to be manually renamed following the previous steps." ] }, { "cell_type": "code", "execution_count": 31, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
Unnamed: 0idevent_idtype_idperiod_idminsecteam_idoutcomexytimestamplast_modifiedversionplayer_idkeypassassistisLongBallisGoalMouthYCoordinateisGoalMouthZCoordinateisThrowInisVolleyisKeeperThrowisGoalKickisDirectionOfPlayisFoulisTeamFormationisTeamPlayerFormationisOwnPlayerisPassEndXisPassEndYisDeletedEventTypeisFormationSlotisBlockedXCoordinateisBlockedYCoordinateisHeadisDirectisNotPastGoalLineisIntentionalAssistisChippedisLayOffisLaunchisOutOfPlayisFlickOnisBoxCentreisLeadingToGoalisParriedSafeisParriedDangerisCollectedisStandingisDivingisOutOfBoxCentreisStoopingisHandsisFeetisBlockedCrossisPlayerNotVisibleisCaptainisSwitchOfPlayisTeamKitisGkKickFromHandsisCrossisRightFootedisGameEndisOtherBodyPartisAssistisOverrunisLengthisAngleisBigChanceisIndividualPlayisRegularPlayisInswingerisOutswingerisStraightisResumeisOwnShotBlockedisPostMatchCompleteisGkXCoordinateisGkYCoordinateisOppositeRelatedEventIdisBlockedPassisLowisSetPieceisGkStartisIndirectisFromCornerisTemp_BlockedisOpenRoofisAirHumidityisAirPressureisCelsiusDegreesisAttemptedTackleisKickOffisDefensiveisOffensiveisOverArmisAssistedisDetailedPositionIdisPositionSideIdisShovePushisShirtPullHoldingisHeadPassisInvolvedisChecksCompleteisYellowCardisFirstTouchisThroughBallisInjuryisTacticalisPlayerPositionisConditionsisFieldPitchisAttendanceFigureisFreeKickTakenisInjuredPlayerIdisRelatedEventIdisZoneisEndTypeisJerseyNumberisCornerTakenisBoxRightisBoxLeftisBoxDeepLeftisPlayersCaughtOffsideisLeftFootedisLeftisHighisRightisLowLeftisLowCentreisLowRightisHighRightisBlockedisCloseLeftisHighClaimis1On1isDefBlockevent_name
01233864464713416001310.00.02021-10-03T13:00:03.3702021-10-03T14:00:201633266020074NaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN2.01, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0, 0, 0, 0,...NaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN17745.0NaN4973.0NaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0...NaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN17745, 166477, 40146, 197469, 218031, 93100, 2...NaNNaNNaNNaNNaNNaN1, 2, 2, 3, 2, 2, 3, 3, 4, 4, 3, 5, 5, 5, 5, 5...NaNNaNNaNNaNNaNNaNNaNNaN1, 27, 5, 20, 4, 23, 37, 8, 9, 14, 7, 10, 11, ...NaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNisTeamSetUp
\n", "
" ], "text/plain": [ " Unnamed: 0 id event_id type_id period_id min sec team_id \\\n", "0 1 2338644647 1 34 16 0 0 13 \n", "\n", " outcome x y timestamp last_modified \\\n", "0 1 0.0 0.0 2021-10-03T13:00:03.370 2021-10-03T14:00:20 \n", "\n", " version player_id keypass assist isLongBall \\\n", "0 1633266020074 NaN NaN NaN NaN \n", "\n", " isGoalMouthYCoordinate isGoalMouthZCoordinate isThrowIn isVolley \\\n", "0 NaN NaN NaN NaN \n", "\n", " isKeeperThrow isGoalKick isDirectionOfPlay isFoul isTeamFormation \\\n", "0 NaN NaN NaN NaN 2.0 \n", "\n", " isTeamPlayerFormation isOwnPlayer isPassEndX \\\n", "0 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0, 0, 0, 0,... NaN NaN \n", "\n", " isPassEndY isDeletedEventType isFormationSlot isBlockedXCoordinate \\\n", "0 NaN NaN NaN NaN \n", "\n", " isBlockedYCoordinate isHead isDirect isNotPastGoalLine \\\n", "0 NaN NaN NaN NaN \n", "\n", " isIntentionalAssist isChipped isLayOff isLaunch isOutOfPlay isFlickOn \\\n", "0 NaN NaN NaN NaN NaN NaN \n", "\n", " isBoxCentre isLeadingToGoal isParriedSafe isParriedDanger isCollected \\\n", "0 NaN NaN NaN NaN NaN \n", "\n", " isStanding isDiving isOutOfBoxCentre isStooping isHands isFeet \\\n", "0 NaN NaN NaN NaN NaN NaN \n", "\n", " isBlockedCross isPlayerNotVisible isCaptain isSwitchOfPlay isTeamKit \\\n", "0 NaN NaN 17745.0 NaN 4973.0 \n", "\n", " isGkKickFromHands isCross isRightFooted isGameEnd isOtherBodyPart \\\n", "0 NaN NaN NaN NaN NaN \n", "\n", " isAssist isOverrun isLength isAngle isBigChance isIndividualPlay \\\n", "0 NaN NaN NaN NaN NaN NaN \n", "\n", " isRegularPlay isInswinger isOutswinger isStraight \\\n", "0 NaN NaN NaN NaN \n", "\n", " isResume isOwnShotBlocked \\\n", "0 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0... NaN \n", "\n", " isPostMatchComplete isGkXCoordinate isGkYCoordinate \\\n", "0 NaN NaN NaN \n", "\n", " isOppositeRelatedEventId isBlockedPass isLow isSetPiece isGkStart \\\n", "0 NaN NaN NaN NaN NaN \n", "\n", " isIndirect isFromCorner isTemp_Blocked isOpenRoof isAirHumidity \\\n", "0 NaN NaN NaN NaN NaN \n", "\n", " isAirPressure isCelsiusDegrees isAttemptedTackle isKickOff isDefensive \\\n", "0 NaN NaN NaN NaN NaN \n", "\n", " isOffensive isOverArm isAssisted isDetailedPositionId isPositionSideId \\\n", "0 NaN NaN NaN NaN NaN \n", "\n", " isShovePush isShirtPullHolding isHeadPass \\\n", "0 NaN NaN NaN \n", "\n", " isInvolved isChecksComplete \\\n", "0 17745, 166477, 40146, 197469, 218031, 93100, 2... NaN \n", "\n", " isYellowCard isFirstTouch isThroughBall isInjury isTactical \\\n", "0 NaN NaN NaN NaN NaN \n", "\n", " isPlayerPosition isConditions \\\n", "0 1, 2, 2, 3, 2, 2, 3, 3, 4, 4, 3, 5, 5, 5, 5, 5... NaN \n", "\n", " isFieldPitch isAttendanceFigure isFreeKickTaken isInjuredPlayerId \\\n", "0 NaN NaN NaN NaN \n", "\n", " isRelatedEventId isZone isEndType \\\n", "0 NaN NaN NaN \n", "\n", " isJerseyNumber isCornerTaken \\\n", "0 1, 27, 5, 20, 4, 23, 37, 8, 9, 14, 7, 10, 11, ... NaN \n", "\n", " isBoxRight isBoxLeft isBoxDeepLeft isPlayersCaughtOffside isLeftFooted \\\n", "0 NaN NaN NaN NaN NaN \n", "\n", " isLeft isHigh isRight isLowLeft isLowCentre isLowRight isHighRight \\\n", "0 NaN NaN NaN NaN NaN NaN NaN \n", "\n", " isBlocked isCloseLeft isHighClaim is1On1 isDefBlock event_name \n", "0 NaN NaN NaN NaN NaN isTeamSetUp " ] }, "execution_count": 31, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_cry_lei_events.head(1)" ] }, { "cell_type": "code", "execution_count": 32, "metadata": {}, "outputs": [], "source": [ "# Define function to \n", "def rename_columns(df):\n", " \n", " \"\"\"\n", " Function to...\n", " \"\"\"\n", " \n", " ## Rename columns\n", " df = df.rename(columns={'keypass': 'isKeyPass',\n", " 'assist': 'isAssist',\n", " 'isGoalMouthXCoordinate': 'GoalMouthXCoordinate',\n", " 'isGoalMouthYCoordinate': 'GoalMouthYCoordinate',\n", " 'isDirectionOfPlay': 'DirectionOfPlay',\n", " 'isTeamFormation': 'TeamFormation',\n", " 'isTeamPlayerFormation': 'TeamPlayerFormation',\n", " 'isPassEndX': 'PassEndX',\n", " 'isPassEndY': 'PassEndY',\n", " 'isDeletedEventType': 'DeletedEventType',\n", " 'isFormationSlot': 'FormationSlot',\n", " 'isBlockedXCoordinate': 'BlockedXCoordinate',\n", " 'isBlockedYCoordinate': 'BlockedYCoordinate',\n", " 'isCaptain': 'Captain',\n", " 'isTeamKit': 'TeamKit',\n", " 'isLength': 'Length',\n", " 'isAngle': 'Angle',\n", " 'isResume': 'Resume',\n", " 'isGkXCoordinate': 'GkXCoordinate',\n", " 'isGkYCoordinate': 'GkYCoordinate',\n", " 'isOppositeRelatedEventId': 'OppositeRelatedEventId',\n", " 'isAirHumidity': 'AirHumidity',\n", " 'isAirPressure': 'AirPressure',\n", " 'isCelsiusDegrees': 'CelSiusDegrees',\n", " 'isKickOff': 'KickOff',\n", " 'isDetailedPositionId': 'DetailedPositionId',\n", " 'isPositionsSideId': 'PositionsSideId',\n", " 'isInvolved': 'Involved',\n", " 'isInjury': 'Injury',\n", " 'isPlayerPosition': 'PlayerPosition',\n", " 'isConditions': 'Conditions',\n", " 'isFieldPitch': 'FieldPitch',\n", " 'isAttendanceFigure': 'AttendanceFigure',\n", " 'isInjuredPlayerId': 'InjuredPlayerId',\n", " 'isRelatedEventId': 'RelatedEventId',\n", " 'isZone': 'Zone',\n", " 'isJerseyNumber': 'JerseyNumber',\n", " 'isPlayersCaughtOffside': 'PlayersCaughtOffside'\n", " }\n", " )\n", " \n", " ## Return DataFrame\n", " return df" ] }, { "cell_type": "code", "execution_count": 33, "metadata": {}, "outputs": [], "source": [ "# Apply Clean Qualifier ID columns function\n", "df_cry_lei_events = rename_columns(df_cry_lei_events)\n", "df_cry_bri_events = rename_columns(df_cry_bri_events)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "\n", "### 4.07. Clean Qualifier Attributes\n", "The Qualifier attributes are filled with various values, including NULL, 0, 1, and -1. These are to be cleaned " ] }, { "cell_type": "code", "execution_count": 34, "metadata": {}, "outputs": [], "source": [ "# Define function to \n", "def clean_qualifiers(df):\n", " \n", " \"\"\"\n", " Function to...\n", " \"\"\"\n", " \n", " ##\n", " \n", " ###\n", " lst_cols = []\n", "\n", " ###\n", " for col in df_cry_lei_events.columns:\n", " if 'is' in col:\n", " lst_cols.append(col)\n", " \n", " \n", " ##\n", " for col in lst_cols:\n", " try:\n", " df[col] = df[col].fillna(0)\n", " df[col] = df[col].replace({-1: 1})\n", " except:\n", " pass\n", " \n", " ## Return DataFrame\n", " return df" ] }, { "cell_type": "code", "execution_count": 35, "metadata": {}, "outputs": [], "source": [ "# Apply Clean Qualifiers function\n", "df_cry_lei_events = clean_qualifiers(df_cry_lei_events)\n", "df_cry_bri_events = clean_qualifiers(df_cry_bri_events)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "\n", "### 4.08. Add Player Information" ] }, { "cell_type": "code", "execution_count": 36, "metadata": {}, "outputs": [], "source": [ "# Define function to \n", "def join_event_player_dfs(df_events, df_players):\n", " \n", " \"\"\"\n", " Function to...\n", " \"\"\"\n", " \n", " ## Create features\n", " df_events = pd.merge(df_events, df_players, left_on=['player_id'], right_on=['player_id'], how='left')\n", " \n", " ## Return DataFrame\n", " return df_events" ] }, { "cell_type": "code", "execution_count": 37, "metadata": {}, "outputs": [], "source": [ "# Apply Create Multifeature Attributes function\n", "df_cry_lei_events = join_event_player_dfs(df_cry_lei_events, df_cry_lei_players)\n", "df_cry_bri_events = join_event_player_dfs(df_cry_bri_events, df_cry_bri_players)" ] }, { "cell_type": "code", "execution_count": 38, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
indexplayer_idFirstNameLastNameFullNameFormation_PlacePositionJerseyNoStatusteam_HATimeOnTimeOffMins.PlayedMatchID
01101668JamieVardyJamie Vardy9Striker9Start00.096.096.0f2210334
\n", "
" ], "text/plain": [ " index player_id FirstName LastName FullName Formation_Place Position \\\n", "0 1 101668 Jamie Vardy Jamie Vardy 9 Striker \n", "\n", " JerseyNo Status team_HA TimeOn TimeOff Mins.Played MatchID \n", "0 9 Start 0 0.0 96.0 96.0 f2210334 " ] }, "execution_count": 38, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_cry_lei_players.head(1)" ] }, { "cell_type": "code", "execution_count": 39, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
indexplayer_idFirstNameLastNameFullNameFormation_PlacePositionJerseyNoStatusteam_HATimeOnTimeOffMins.PlayedMatchID
01105666JackButlandJack Butland0Substitute1Sub1NaNNaNNaNf2210324
\n", "
" ], "text/plain": [ " index player_id FirstName LastName FullName Formation_Place \\\n", "0 1 105666 Jack Butland Jack Butland 0 \n", "\n", " Position JerseyNo Status team_HA TimeOn TimeOff Mins.Played \\\n", "0 Substitute 1 Sub 1 NaN NaN NaN \n", "\n", " MatchID \n", "0 f2210324 " ] }, "execution_count": 39, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_cry_bri_players.head(1)" ] }, { "cell_type": "code", "execution_count": 40, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
Unnamed: 0idevent_idtype_idperiod_idminsecteam_idoutcomexytimestamplast_modifiedversionplayer_idisKeyPassisAssistisLongBallGoalMouthYCoordinateisGoalMouthZCoordinateisThrowInisVolleyisKeeperThrowisGoalKickDirectionOfPlayisFoulTeamFormationTeamPlayerFormationisOwnPlayerPassEndXPassEndYDeletedEventTypeFormationSlotBlockedXCoordinateBlockedYCoordinateisHeadisDirectisNotPastGoalLineisIntentionalAssistisChippedisLayOffisLaunchisOutOfPlayisFlickOnisBoxCentreisLeadingToGoalisParriedSafeisParriedDangerisCollectedisStandingisDivingisOutOfBoxCentreisStoopingisHandsisFeetisBlockedCrossisPlayerNotVisibleCaptainisSwitchOfPlayTeamKitisGkKickFromHandsisCrossisRightFootedisGameEndisOtherBodyPartisAssistisOverrunLengthAngleisBigChanceisIndividualPlayisRegularPlayisInswingerisOutswingerisStraightResumeisOwnShotBlockedisPostMatchCompleteGkXCoordinateGkYCoordinateOppositeRelatedEventIdisBlockedPassisLowisSetPieceisGkStartisIndirectisFromCornerisTemp_BlockedisOpenRoofAirHumidityAirPressureCelSiusDegreesisAttemptedTackleKickOffisDefensiveisOffensiveisOverArmisAssistedDetailedPositionIdisPositionSideIdisShovePushisShirtPullHoldingisHeadPassInvolvedisChecksCompleteisYellowCardisFirstTouchisThroughBallInjuryisTacticalPlayerPositionConditionsFieldPitchAttendanceFigureisFreeKickTakenInjuredPlayerIdRelatedEventIdZoneisEndTypeJerseyNumberisCornerTakenisBoxRightisBoxLeftisBoxDeepLeftPlayersCaughtOffsideisLeftFootedisLeftisHighisRightisLowLeftisLowCentreisLowRightisHighRightisBlockedisCloseLeftisHighClaimis1On1isDefBlockevent_nameindexFirstNameLastNameFullNameFormation_PlacePositionJerseyNoStatusteam_HATimeOnTimeOffMins.PlayedMatchID
01233864464713416001310.00.02021-10-03T13:00:03.3702021-10-03T14:00:201633266020074NaN0.00.00.0NaN0.00.00.00.00.0NaN0.02.01, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0, 0, 0, 0,...0.0NaNNaNNaNNaNNaNNaN0.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.017745.00.04973.00.00.00.00.00.00.00.0NaNNaN0.00.00.00.00.00.00, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0...0.00.0NaNNaNNaN0.00.00.00.00.00.00.00.0NaNNaNNaN0.0NaN0.00.00.00.0NaN0.00.00.00.017745, 166477, 40146, 197469, 218031, 93100, 2...0.00.00.00.0NaN0.01, 2, 2, 3, 2, 2, 3, 3, 4, 4, 3, 5, 5, 5, 5, 5...NaNNaNNaN0.0NaNNaNNaN0.01, 27, 5, 20, 4, 23, 37, 8, 9, 14, 7, 10, 11, ...0.00.00.00.0NaN0.00.00.00.00.00.00.00.00.00.00.00.00.0isTeamSetUpNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN
\n", "
" ], "text/plain": [ " Unnamed: 0 id event_id type_id period_id min sec team_id \\\n", "0 1 2338644647 1 34 16 0 0 13 \n", "\n", " outcome x y timestamp last_modified \\\n", "0 1 0.0 0.0 2021-10-03T13:00:03.370 2021-10-03T14:00:20 \n", "\n", " version player_id isKeyPass isAssist isLongBall \\\n", "0 1633266020074 NaN 0.0 0.0 0.0 \n", "\n", " GoalMouthYCoordinate isGoalMouthZCoordinate isThrowIn isVolley \\\n", "0 NaN 0.0 0.0 0.0 \n", "\n", " isKeeperThrow isGoalKick DirectionOfPlay isFoul TeamFormation \\\n", "0 0.0 0.0 NaN 0.0 2.0 \n", "\n", " TeamPlayerFormation isOwnPlayer PassEndX \\\n", "0 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0, 0, 0, 0,... 0.0 NaN \n", "\n", " PassEndY DeletedEventType FormationSlot BlockedXCoordinate \\\n", "0 NaN NaN NaN NaN \n", "\n", " BlockedYCoordinate isHead isDirect isNotPastGoalLine \\\n", "0 NaN 0.0 0.0 0.0 \n", "\n", " isIntentionalAssist isChipped isLayOff isLaunch isOutOfPlay isFlickOn \\\n", "0 0.0 0.0 0.0 0.0 0.0 0.0 \n", "\n", " isBoxCentre isLeadingToGoal isParriedSafe isParriedDanger isCollected \\\n", "0 0.0 0.0 0.0 0.0 0.0 \n", "\n", " isStanding isDiving isOutOfBoxCentre isStooping isHands isFeet \\\n", "0 0.0 0.0 0.0 0.0 0.0 0.0 \n", "\n", " isBlockedCross isPlayerNotVisible Captain isSwitchOfPlay TeamKit \\\n", "0 0.0 0.0 17745.0 0.0 4973.0 \n", "\n", " isGkKickFromHands isCross isRightFooted isGameEnd isOtherBodyPart \\\n", "0 0.0 0.0 0.0 0.0 0.0 \n", "\n", " isAssist isOverrun Length Angle isBigChance isIndividualPlay \\\n", "0 0.0 0.0 NaN NaN 0.0 0.0 \n", "\n", " isRegularPlay isInswinger isOutswinger isStraight \\\n", "0 0.0 0.0 0.0 0.0 \n", "\n", " Resume isOwnShotBlocked \\\n", "0 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0... 0.0 \n", "\n", " isPostMatchComplete GkXCoordinate GkYCoordinate OppositeRelatedEventId \\\n", "0 0.0 NaN NaN NaN \n", "\n", " isBlockedPass isLow isSetPiece isGkStart isIndirect isFromCorner \\\n", "0 0.0 0.0 0.0 0.0 0.0 0.0 \n", "\n", " isTemp_Blocked isOpenRoof AirHumidity AirPressure CelSiusDegrees \\\n", "0 0.0 0.0 NaN NaN NaN \n", "\n", " isAttemptedTackle KickOff isDefensive isOffensive isOverArm isAssisted \\\n", "0 0.0 NaN 0.0 0.0 0.0 0.0 \n", "\n", " DetailedPositionId isPositionSideId isShovePush isShirtPullHolding \\\n", "0 NaN 0.0 0.0 0.0 \n", "\n", " isHeadPass Involved \\\n", "0 0.0 17745, 166477, 40146, 197469, 218031, 93100, 2... \n", "\n", " isChecksComplete isYellowCard isFirstTouch isThroughBall Injury \\\n", "0 0.0 0.0 0.0 0.0 NaN \n", "\n", " isTactical PlayerPosition Conditions \\\n", "0 0.0 1, 2, 2, 3, 2, 2, 3, 3, 4, 4, 3, 5, 5, 5, 5, 5... NaN \n", "\n", " FieldPitch AttendanceFigure isFreeKickTaken InjuredPlayerId \\\n", "0 NaN NaN 0.0 NaN \n", "\n", " RelatedEventId Zone isEndType \\\n", "0 NaN NaN 0.0 \n", "\n", " JerseyNumber isCornerTaken \\\n", "0 1, 27, 5, 20, 4, 23, 37, 8, 9, 14, 7, 10, 11, ... 0.0 \n", "\n", " isBoxRight isBoxLeft isBoxDeepLeft PlayersCaughtOffside isLeftFooted \\\n", "0 0.0 0.0 0.0 NaN 0.0 \n", "\n", " isLeft isHigh isRight isLowLeft isLowCentre isLowRight isHighRight \\\n", "0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 \n", "\n", " isBlocked isCloseLeft isHighClaim is1On1 isDefBlock event_name \\\n", "0 0.0 0.0 0.0 0.0 0.0 isTeamSetUp \n", "\n", " index FirstName LastName FullName Formation_Place Position JerseyNo \\\n", "0 NaN NaN NaN NaN NaN NaN NaN \n", "\n", " Status team_HA TimeOn TimeOff Mins.Played MatchID \n", "0 NaN NaN NaN NaN NaN NaN " ] }, "execution_count": 40, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_cry_lei_events.head(1)" ] }, { "cell_type": "code", "execution_count": 41, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
Unnamed: 0idevent_idtype_idperiod_idminsecteam_idoutcomexytimestamplast_modifiedversionplayer_idisKeyPassisAssistisLongBallisHandisSixYardBlockedGoalMouthYCoordinateisGoalMouthZCoordinateisThrowInisVolleyisKeeperThrowisGoalKickDirectionOfPlayisFoulTeamFormationTeamPlayerFormationisDeflectionisOwnPlayerPassEndXPassEndYDeletedEventTypeFormationSlotBlockedXCoordinateBlockedYCoordinateisHeadisDirectisIntentionalAssistisChippedisLayOffisLaunchisOutOfPlayisFlickOnisBoxCentreisParriedSafeisCollectedisStandingisDivingisOutOfBoxCentreisStoopingisReachingisHandsisBlockedCrossisScoredisPlayerNotVisibleCaptainisSwitchOfPlayTeamKitisGkHoofisGkKickFromHandsisCrossisRightFootedisGameEndisOtherBodyPartisAssistisOverrunLengthAngleisBigChanceisIndividualPlayisRegularPlayisInswingerisOutswingerisStraightResumeisOwnShotBlockedisPostMatchCompleteGkXCoordinateGkYCoordinateisUnchallengedOppositeRelatedEventIdisBlockedPassisLowisFairPlayisSetPieceisGkStartisIndirectisFromCornerisOpenRoofAirHumidityAirPressureCelSiusDegreesisFreeKickisAerialFoulisAttemptedTackleisMinutesKickOffisFantasyAssistTypeisFantasyAssistedByisFantasyAssistTeamisDefensiveisOffensiveisOverArmisAssistedDetailedPositionIdisPositionSideIdisShovePushisShirtPullHoldingisHeadPassInvolvedisChecksCompleteisYellowCardisCaptainChangeisFirstTouchisArgumentisExcessiveCelebrationisThroughBallInjuryisTacticalPlayerPositionConditionsFieldPitchAttendanceFigureisFreeKickTakenInjuredPlayerIdRelatedEventIdZoneisEndTypeJerseyNumberisCornerTakenisBoxRightisBoxLeftPlayersCaughtOffsideisLeftFootedisLeftisHighisRightisLowLeftisHighLeftisLowCentreisLowRightisBlockedisCloseRightisHighClaimisPenaltyisDefBlockevent_nameindexFirstNameLastNameFullNameFormation_PlacePositionJerseyNoStatusteam_HATimeOnTimeOffMins.PlayedMatchID
01233615768113416003110.00.02021-09-27T19:00:03.2782021-09-27T19:06:571632766017629NaN0.00.00.0NaNNaNNaN0.00.00.00.00.0NaN0.04.01, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0, 0, 0, 0,...NaN0.0NaNNaNNaNNaNNaNNaN0.00.00.00.00.00.00.00.00.00.00.00.00.00.00.0NaN0.00.0NaN0.066975.00.0406.0NaN0.00.00.00.00.00.00.0NaNNaN0.00.00.00.00.00.00, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0...0.00.0NaNNaNNaNNaN0.00.0NaN0.00.00.00.00.0NaNNaNNaNNaNNaN0.0NaNNaNNaNNaNNaN0.00.00.00.0NaN0.00.00.00.040836, 55494, 244723, 66975, 174874, 209036, 2...0.00.0NaN0.0NaNNaN0.0NaN0.01, 2, 2, 3, 2, 2, 3, 3, 4, 4, 4, 5, 5, 5, 5, 5...NaNNaNNaN0.0NaNNaNNaN0.013, 2, 3, 4, 16, 6, 23, 18, 22, 9, 11, 1, 7, 8...0.00.00.0NaN0.00.00.00.00.0NaN0.00.00.0NaN0.0NaN0.0isTeamSetUpNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN
\n", "
" ], "text/plain": [ " Unnamed: 0 id event_id type_id period_id min sec team_id \\\n", "0 1 2336157681 1 34 16 0 0 31 \n", "\n", " outcome x y timestamp last_modified \\\n", "0 1 0.0 0.0 2021-09-27T19:00:03.278 2021-09-27T19:06:57 \n", "\n", " version player_id isKeyPass isAssist isLongBall isHand \\\n", "0 1632766017629 NaN 0.0 0.0 0.0 NaN \n", "\n", " isSixYardBlocked GoalMouthYCoordinate isGoalMouthZCoordinate isThrowIn \\\n", "0 NaN NaN 0.0 0.0 \n", "\n", " isVolley isKeeperThrow isGoalKick DirectionOfPlay isFoul TeamFormation \\\n", "0 0.0 0.0 0.0 NaN 0.0 4.0 \n", "\n", " TeamPlayerFormation isDeflection \\\n", "0 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0, 0, 0, 0,... NaN \n", "\n", " isOwnPlayer PassEndX PassEndY DeletedEventType FormationSlot \\\n", "0 0.0 NaN NaN NaN NaN \n", "\n", " BlockedXCoordinate BlockedYCoordinate isHead isDirect \\\n", "0 NaN NaN 0.0 0.0 \n", "\n", " isIntentionalAssist isChipped isLayOff isLaunch isOutOfPlay isFlickOn \\\n", "0 0.0 0.0 0.0 0.0 0.0 0.0 \n", "\n", " isBoxCentre isParriedSafe isCollected isStanding isDiving \\\n", "0 0.0 0.0 0.0 0.0 0.0 \n", "\n", " isOutOfBoxCentre isStooping isReaching isHands isBlockedCross \\\n", "0 0.0 0.0 NaN 0.0 0.0 \n", "\n", " isScored isPlayerNotVisible Captain isSwitchOfPlay TeamKit isGkHoof \\\n", "0 NaN 0.0 66975.0 0.0 406.0 NaN \n", "\n", " isGkKickFromHands isCross isRightFooted isGameEnd isOtherBodyPart \\\n", "0 0.0 0.0 0.0 0.0 0.0 \n", "\n", " isAssist isOverrun Length Angle isBigChance isIndividualPlay \\\n", "0 0.0 0.0 NaN NaN 0.0 0.0 \n", "\n", " isRegularPlay isInswinger isOutswinger isStraight \\\n", "0 0.0 0.0 0.0 0.0 \n", "\n", " Resume isOwnShotBlocked \\\n", "0 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0... 0.0 \n", "\n", " isPostMatchComplete GkXCoordinate GkYCoordinate isUnchallenged \\\n", "0 0.0 NaN NaN NaN \n", "\n", " OppositeRelatedEventId isBlockedPass isLow isFairPlay isSetPiece \\\n", "0 NaN 0.0 0.0 NaN 0.0 \n", "\n", " isGkStart isIndirect isFromCorner isOpenRoof AirHumidity AirPressure \\\n", "0 0.0 0.0 0.0 0.0 NaN NaN \n", "\n", " CelSiusDegrees isFreeKick isAerialFoul isAttemptedTackle isMinutes \\\n", "0 NaN NaN NaN 0.0 NaN \n", "\n", " KickOff isFantasyAssistType isFantasyAssistedBy isFantasyAssistTeam \\\n", "0 NaN NaN NaN NaN \n", "\n", " isDefensive isOffensive isOverArm isAssisted DetailedPositionId \\\n", "0 0.0 0.0 0.0 0.0 NaN \n", "\n", " isPositionSideId isShovePush isShirtPullHolding isHeadPass \\\n", "0 0.0 0.0 0.0 0.0 \n", "\n", " Involved isChecksComplete \\\n", "0 40836, 55494, 244723, 66975, 174874, 209036, 2... 0.0 \n", "\n", " isYellowCard isCaptainChange isFirstTouch isArgument \\\n", "0 0.0 NaN 0.0 NaN \n", "\n", " isExcessiveCelebration isThroughBall Injury isTactical \\\n", "0 NaN 0.0 NaN 0.0 \n", "\n", " PlayerPosition Conditions FieldPitch \\\n", "0 1, 2, 2, 3, 2, 2, 3, 3, 4, 4, 4, 5, 5, 5, 5, 5... NaN NaN \n", "\n", " AttendanceFigure isFreeKickTaken InjuredPlayerId RelatedEventId Zone \\\n", "0 NaN 0.0 NaN NaN NaN \n", "\n", " isEndType JerseyNumber \\\n", "0 0.0 13, 2, 3, 4, 16, 6, 23, 18, 22, 9, 11, 1, 7, 8... \n", "\n", " isCornerTaken isBoxRight isBoxLeft PlayersCaughtOffside isLeftFooted \\\n", "0 0.0 0.0 0.0 NaN 0.0 \n", "\n", " isLeft isHigh isRight isLowLeft isHighLeft isLowCentre isLowRight \\\n", "0 0.0 0.0 0.0 0.0 NaN 0.0 0.0 \n", "\n", " isBlocked isCloseRight isHighClaim isPenalty isDefBlock event_name \\\n", "0 0.0 NaN 0.0 NaN 0.0 isTeamSetUp \n", "\n", " index FirstName LastName FullName Formation_Place Position JerseyNo \\\n", "0 NaN NaN NaN NaN NaN NaN NaN \n", "\n", " Status team_HA TimeOn TimeOff Mins.Played MatchID \n", "0 NaN NaN NaN NaN NaN NaN " ] }, "execution_count": 41, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_cry_bri_events.head(1)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "\n", "### 4.09. Create Multifeature Attributes\n", "Created using the 'Useful Queries' section of the Opta F24 documentation (pages 26-31)." ] }, { "cell_type": "code", "execution_count": 42, "metadata": {}, "outputs": [], "source": [ "# Define function to \n", "def create_multifeature_attributes(df):\n", " \n", " \"\"\"\n", " Function to...\n", " \"\"\"\n", " \n", " ## Create blank columns if they don't exist - temp fix\n", " if 'isAerialFoul' not in df:\n", " df['isAerialFoul'] = 0\n", " \n", " if 'isHand' not in df:\n", " df['isHand'] = 0\n", "\n", " if 'isOwnGoal' not in df:\n", " df['isOwnGoal'] = 0\n", "\n", " if 'isPenalty' not in df:\n", " df['isPenalty'] = 0 \n", "\n", " if 'isYellowCard' not in df:\n", " df['isYellowCard'] = 0 \n", "\n", " if 'isSecondYellow' not in df:\n", " df['isSecondYellow'] = 0\n", "\n", " if 'isRedCard' not in df:\n", " df['isRedCard'] = 0 \n", "\n", " \n", " ## Create features\n", " df['isPass'] = np.where( (df['type_id'] == 1) &\n", " ((df['isCross'] != 1) &\n", " (df['isThrowIn'] != 1) &\n", " (df['isKeeperThrow'] != 1)\n", " ) \n", " , 1, 0\n", " )\n", " df['isPassSuccessful'] = np.where( (df['type_id'] == 1) &\n", " (df['outcome'] == 1) &\n", " ((df['isCross'] != 1) &\n", " (df['isThrowIn'] != 1) &\n", " (df['isKeeperThrow'] != 1)\n", " ) \n", " , 1, 0\n", " )\n", " df['isPassUnsuccessful'] = np.where( (df['type_id'] == 1) &\n", " (df['outcome'] == 0) &\n", " ((df['isCross'] != 1) &\n", " (df['isThrowIn'] != 1) &\n", " (df['isKeeperThrow'] != 1)\n", " ) \n", " , 1, 0\n", " )\n", " df['isCrossOP'] = np.where( (df['type_id'] == 1) &\n", " (df['isCross'] == 1) &\n", " ((df['isFreeKickTaken'] != 1) &\n", " (df['isCornerTaken'] != 1)\n", " ) \n", " , 1, 0\n", " )\n", " df['isCrossOPSuccessful'] = np.where( (df['type_id'] == 1) &\n", " (df['outcome'] == 1) &\n", " (df['isCross'] == 1) &\n", " ((df['isFreeKickTaken'] != 1) &\n", " (df['isCornerTaken'] != 1)\n", " ) \n", " , 1, 0\n", " )\n", " df['isCrossOPUnsuccessful'] = np.where( (df['type_id'] == 1) &\n", " (df['outcome'] == 0) &\n", " (df['isCross'] == 1) &\n", " ((df['isFreeKickTaken'] != 1) &\n", " (df['isCornerTaken'] != 1)\n", " ) \n", " , 1, 0\n", " )\n", " df['isAssist'] = np.where( (df['type_id'] == 16) &\n", " (df['outcome'] == 1) &\n", " (df['isAssisted'] == 1) &\n", " #(df['isRelevantEventID'] == 1) & # not in this dataset\n", " ((df['isFreeKickTaken'] != 1) &\n", " (df['isCornerTaken'] != 1)\n", " ) \n", " , 1, 0\n", " )\n", " df['isKeyPass'] = np.where(((df['type_id'] == 13) |\n", " (df['type_id'] == 14) |\n", " (df['type_id'] == 15) |\n", " (df['type_id'] == 60)\n", " ) &\n", " (df['isAssisted'] == 1) #&\n", " #(df['isRelevantEventID'] == 1) & # not in this dataset\n", " , 1, 0\n", " )\n", " df['isOffensivePass'] = np.where( (df['type_id'] == 1) &\n", " (df['x'] < (df['PassEndX'])) &\n", " ((df['isCross'] != 1) &\n", " (df['isThrowIn'] != 1) &\n", " (df['isKeeperThrow'] != 1)\n", " ) \n", " , 1, 0\n", " )\n", " df['isOffensivePassWon'] = np.where( (df['type_id'] == 1) &\n", " (df['outcome'] == 1) & \n", " (df['x'] < (df['PassEndX'])) &\n", " ((df['isCross'] != 1) &\n", " (df['isThrowIn'] != 1) &\n", " (df['isKeeperThrow'] != 1)\n", " ) \n", " , 1, 0\n", " )\n", " df['isOffensivePassLost'] = np.where( (df['type_id'] == 1) &\n", " (df['outcome'] == 0) & \n", " (df['x'] < (df['PassEndX'])) &\n", " ((df['isCross'] != 1) &\n", " (df['isThrowIn'] != 1) &\n", " (df['isKeeperThrow'] != 1)\n", " ) \n", " , 1, 0\n", " )\n", " df['isBackwardPass'] = np.where( (df['type_id'] == 1) &\n", " (df['x'] > (df['PassEndX'])) &\n", " ((df['isCross'] != 1) &\n", " (df['isThrowIn'] != 1) &\n", " (df['isKeeperThrow'] != 1)\n", " ) \n", " , 1, 0\n", " )\n", " df['isSidewayPass'] = np.where( (df['type_id'] == 1) &\n", " (df['x'] == (df['PassEndX'])) &\n", " ((df['isCross'] != 1) &\n", " (df['isThrowIn'] != 1) &\n", " (df['isKeeperThrow'] != 1)\n", " ) \n", " , 1, 0\n", " )\n", " df['isLongPass'] = np.where( (df['type_id'] == 1) &\n", " (df['isLongBall'] == 1) &\n", " ((df['isCross'] != 1) &\n", " (df['isThrowIn'] != 1) &\n", " (df['isKeeperThrow'] != 1)\n", " ) \n", " , 1, 0\n", " )\n", " df['isLongPassWon'] = np.where( (df['type_id'] == 1) &\n", " (df['outcome'] == 1) & \n", " (df['isLongBall'] == 1) &\n", " ((df['isCross'] != 1) &\n", " (df['isThrowIn'] != 1) &\n", " (df['isKeeperThrow'] != 1)\n", " ) \n", " , 1, 0\n", " )\n", " df['isLongPassLost'] = np.where( (df['type_id'] == 1) &\n", " (df['outcome'] == 0) & \n", " (df['isLongBall'] == 1) &\n", " ((df['isCross'] != 1) &\n", " (df['isThrowIn'] != 1) &\n", " (df['isKeeperThrow'] != 1)\n", " ) \n", " , 1, 0\n", " )\n", " df['isAerial'] = np.where(((df['type_id'] == 44) |\n", " (df['type_id'] == 14)\n", " ) &\n", " (df['isAerialFoul'] == 1)\n", " , 1, 0\n", " )\n", " df['isAerialWon'] = np.where(((df['type_id'] == 44) |\n", " (df['type_id'] == 14)\n", " ) &\n", " (df['outcome'] == 1) &\n", " (df['isAerialFoul'] == 1)\n", " , 1, 0\n", " )\n", " df['isAerialLost'] = np.where(((df['type_id'] == 44) |\n", " (df['type_id'] == 14)\n", " ) &\n", " (df['outcome'] == 0) &\n", " (df['isAerialFoul'] == 1)\n", " , 1, 0\n", " )\n", " df['isGroundDuel'] = np.where(((df['type_id'] == 3) |\n", " (df['type_id'] == 4) |\n", " (df['type_id'] == 7) |\n", " (df['type_id'] == 45) |\n", " (df['type_id'] == 54) |\n", " (df['type_id'] == 50)\n", " ) &\n", " (df['isAerialFoul'] == 1)\n", " , 1, 0\n", " )\n", " df['isGroundDuelWon'] = np.where(((df['type_id'] == 3) |\n", " (df['type_id'] == 4) |\n", " (df['type_id'] == 7) |\n", " (df['type_id'] == 45) |\n", " (df['type_id'] == 54) |\n", " (df['type_id'] == 50)\n", " ) &\n", " (df['outcome'] == 1) &\n", " (df['isAerialFoul'] == 1)\n", " , 1, 0\n", " )\n", " df['isGroundDuelLost'] = np.where((((df['type_id'] == 3) |\n", " (df['type_id'] == 4) |\n", " (df['type_id'] == 7) |\n", " (df['type_id'] == 45) |\n", " (df['type_id'] == 54)\n", " ) &\n", " (df['outcome'] == 0) &\n", " (df['isAerialFoul'] == 1)\n", " ) |\n", " ( (df['type_id'] == 50) &\n", " (df['outcome'] == 0)\n", " )\n", " , 1, 0\n", " )\n", " df['isFreeKickTaken'] = np.where((df['type_id'] == 1) &\n", " (df['isFreeKickTaken'] == 1) \n", " , 1, 0\n", " )\n", " df['isFoul'] = np.where(df['type_id'] == 4, 1, 0)\n", " df['isFoulWon'] = np.where((df['type_id'] == 4) &\n", " (df['outcome'] == 1)\n", " , 1, 0\n", " )\n", " df['isFoulConceded'] = np.where((df['type_id'] == 4) &\n", " (df['outcome'] == 0)\n", " , 1, 0\n", " )\n", " df['isHandballConceded'] = np.where((df['type_id'] == 4) &\n", " (df['outcome'] == 0) &\n", " (df['isHand'] == 1)\n", " , 1, 0\n", " )\n", " df['isCorner'] = np.where((df['type_id'] == 1) &\n", " (df['outcome'] == 0) &\n", " (df['isCornerTaken'] == 1)\n", " , 1, 0\n", " )\n", " df['isCrossCorner'] = np.where((df['type_id'] == 1) &\n", " (df['outcome'] == 0) &\n", " (df['isCross'] == 1) &\n", " (df['isCornerTaken'] == 1)\n", " , 1, 0\n", " )\n", " df['isShortCorner'] = np.where((df['type_id'] == 1) &\n", " (df['outcome'] == 0) &\n", " (df['isCornerTaken'] == 1)\n", " , 1, 0\n", " )\n", " df['isCornerIntoBoxSuccessful'] = np.where( (df['type_id'] == 1) &\n", " (df['outcome'] == 1) &\n", " (df['isCornerTaken'] == 1) &\n", " ((df['PassEndX'] > 83) & (df['PassEndX'] <= 100)) &\n", " ((df['PassEndY'] > 21) & (df['PassEndY'] <= 78.9))\n", " , 1, 0\n", " )\n", " df['isCornerIntoBoxUnsuccessful'] = np.where( (df['type_id'] == 1) &\n", " (df['outcome'] == 0) &\n", " (df['isCornerTaken'] == 1) &\n", " ((df['PassEndX'] > 83) & (df['PassEndX'] <= 100)) &\n", " ((df['PassEndY'] > 21) & (df['PassEndY'] <= 78.9))\n", " , 1, 0\n", " )\n", " df['isInterceptions'] = np.where(df['type_id'] == 8, 1, 0)\n", " df['isTackleWon'] = np.where( (df['type_id'] == 7) &\n", " ((df['outcome'] == 1) | \n", " (df['outcome'] == 0)\n", " ), 1, 0\n", " )\n", " df['isTackleLost'] = np.where((df['type_id'] == 45) &\n", " (df['outcome'] == 0)\n", " , 1, 0\n", " )\n", " df['isSave'] = np.where((df['type_id'] == 10) &\n", " (df['outcome'] == 1)\n", " , 1, 0\n", " )\n", " df['isSaveBlockOutfielder'] = np.where((df['type_id'] == 10) &\n", " (df['outcome'] == 1) &\n", " (df['isDefBlock'] == 1)\n", " , 1, 0\n", " )\n", " df['isClaim'] = np.where((df['type_id'] == 11) &\n", " (df['outcome'] == 1)\n", " , 1, 0\n", " )\n", " df['isClearanceLost'] = np.where(df['type_id'] == 12, 1, 0)\n", " df['isHeadedClearanceWon'] = np.where((df['type_id'] == 12) &\n", " (df['outcome'] == 1) &\n", " (df['isHead'] == 1)\n", " , 1, 0\n", " )\n", " df['isHeadedClearanceLost'] = np.where((df['type_id'] == 12) &\n", " (df['outcome'] == 0) &\n", " (df['isHead'] == 1)\n", " , 1, 0\n", " )\n", " df['isShot'] = np.where(((df['type_id'] == 13) |\n", " (df['type_id'] == 14) |\n", " (df['type_id'] == 15) |\n", " (df['type_id'] == 16)\n", " ) &\n", " (df['isOwnGoal'] != 1)\n", " , 1, 0\n", " )\n", " df['isShotOnTarget'] = np.where(((df['type_id'] == 13) |\n", " (df['type_id'] == 14) |\n", " (df['type_id'] == 15) |\n", " (df['type_id'] == 16)\n", " ) &\n", " (df['isOwnGoal'] != 1) &\n", " (df['isBlocked'] != 1)\n", " , 1, 0\n", " )\n", " df['isShotOffTarget'] = np.where((df['type_id'] == 13) |\n", " (df['type_id'] == 14)\n", " , 1, 0\n", " )\n", " df['isShotOP'] = np.where((df['type_id'] == 16) &\n", " (df['isRegularPlay'] == 1)\n", " , 1, 0\n", " )\n", " df['isShotSetPiece'] = np.where((df['type_id'] == 16) &\n", " (df['isSetPiece'] == 1)\n", " , 1, 0\n", " )\n", " df['isShotPenalty'] = np.where((df['type_id'] == 16) &\n", " (df['isPenalty'] == 1)\n", " , 1, 0\n", " )\n", " df['isHeadedShot'] = np.where(((df['type_id'] == 13) |\n", " (df['type_id'] == 14) |\n", " (df['type_id'] == 15) |\n", " (df['type_id'] == 16) |\n", " (df['type_id'] == 24)\n", " ) &\n", " (df['isHead'] == 1)\n", " , 1, 0\n", " )\n", " df['isHeadedShotOnTarget'] = np.where(((df['type_id'] == 15) |\n", " (df['type_id'] == 16)\n", " ) &\n", " (df['isHead'] == 1)\n", " , 1, 0\n", " )\n", " df['isHeadedShotOffTarget'] = np.where(((df['type_id'] == 13) |\n", " (df['type_id'] == 14)\n", " ) &\n", " (df['isHead'] == 1)\n", " , 1, 0\n", " )\n", " df['isGoal'] = np.where((df['type_id'] == 16) &\n", " (df['outcome'] == 1)\n", " , 1, 0\n", " )\n", " df['isGoalOP'] = np.where((df['type_id'] == 16) &\n", " (df['outcome'] == 1) &\n", " (df['isRegularPlay'] == 1)\n", " , 1, 0\n", " )\n", " df['isGoalSetPiece'] = np.where((df['type_id'] == 16) &\n", " (df['outcome'] == 1) &\n", " (df['isSetPiece'] == 1)\n", " , 1, 0\n", " )\n", " df['isGoalPenalty'] = np.where((df['type_id'] == 16) &\n", " (df['outcome'] == 1) &\n", " (df['isPenalty'] == 1)\n", " , 1, 0\n", " )\n", " df['isShotBlockedByOutfielder'] = np.where((df['type_id'] == 15) &\n", " (df['isBlocked'] == 1)\n", " , 1, 0\n", " )\n", " df['isTouch'] = np.where(((df['type_id'] == 1) |\n", " (df['type_id'] == 2) |\n", " (df['type_id'] == 3) |\n", " (df['type_id'] == 4) |\n", " (df['type_id'] == 7) |\n", " (df['type_id'] == 8) |\n", " (df['type_id'] == 9) |\n", " (df['type_id'] == 10) |\n", " (df['type_id'] == 11) |\n", " (df['type_id'] == 12) |\n", " (df['type_id'] == 13) |\n", " (df['type_id'] == 14) |\n", " (df['type_id'] == 15) |\n", " (df['type_id'] == 16) |\n", " (df['type_id'] == 4) |\n", " (df['type_id'] == 41) |\n", " (df['type_id'] == 42) |\n", " (df['type_id'] == 50) |\n", " (df['type_id'] == 54) |\n", " (df['type_id'] == 61) |\n", " (df['type_id'] == 73) |\n", " (df['type_id'] == 74)\n", " ) \n", " , 1, 0\n", " )\n", " df['isSuccessfulTakeOn'] = np.where((df['type_id'] == 3) &\n", " (df['outcome'] == 1)\n", " , 1, 0\n", " )\n", " df['isUnsuccessfulTakeOn'] = np.where((df['type_id'] == 3) &\n", " (df['outcome'] == 0)\n", " , 1, 0\n", " )\n", " df['isOverrun'] = np.where((df['type_id'] == 3) &\n", " (df['outcome'] == 0) &\n", " (df['isOverrun'] == 1)\n", " , 1, 0\n", " )\n", " df['isFoulWon'] = np.where((df['type_id'] == 4) &\n", " (df['outcome'] == 1)\n", " , 1, 0\n", " )\n", " df['isFoulConceded'] = np.where((df['type_id'] == 4) &\n", " (df['outcome'] == 0)\n", " , 1, 0\n", " )\n", " df['isPenaltyConceded'] = np.where((df['type_id'] == 4) &\n", " (df['outcome'] == 0) &\n", " (df['isPenalty'] == 1)\n", " , 1, 0\n", " )\n", " df['isYellowCard'] = np.where((df['type_id'] == 17) &\n", " (df['isYellowCard'] == 1)\n", " , 1, 0\n", " )\n", " df['is2ndYellowCard'] = np.where((df['type_id'] == 17) &\n", " (df['isSecondYellow'] == 1)\n", " , 1, 0\n", " )\n", " df['isRedCard'] = np.where((df['type_id'] == 17) &\n", " (df['isYellowCard'] == 1)\n", " , 1, 0\n", " )\n", " \n", " ## Return DataFrame\n", " return df" ] }, { "cell_type": "code", "execution_count": 43, "metadata": {}, "outputs": [], "source": [ "# Apply Create Multifeature Attributes function\n", "df_cry_lei_events = create_multifeature_attributes(df_cry_lei_events)\n", "df_cry_bri_events = create_multifeature_attributes(df_cry_bri_events)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "\n", "### 4.09. Determine Expected Goals (xG) Values" ] }, { "cell_type": "code", "execution_count": 44, "metadata": {}, "outputs": [], "source": [ "# Load the saved Expected Goals model\n", "xg_model = pickle.load(open(os.path.join(models_dir, 'expected_goals_model_lr.sav'), 'rb'))" ] }, { "cell_type": "code", "execution_count": 45, "metadata": { "scrolled": true }, "outputs": [ { "data": { "text/plain": [ "LogisticRegression(random_state=42)" ] }, "execution_count": 45, "metadata": {}, "output_type": "execute_result" } ], "source": [ "xg_model" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "raw", "metadata": {}, "source": [ "# Define function to \n", "def prepare_xg_df(df, pitch_length_x, pitch_length_y, lr_model):\n", " \n", " \"\"\"\n", " Function to...\n", " \"\"\"\n", " \n", " \n", " ## Data Engineering\n", "\n", " ### Filter DataFrame for shots\n", " df_shots = df[df['isShot'] == 1]\n", "\n", " ### Create new features - 'isFoot', 'distance_to_goal', 'distance_to_center', and 'angle'\n", " df_shots['isFoot'] = np.where(((df_shots['isLeftFooted'] == 1) | (df_shots['isRightFooted'] == 1)) \n", " , 1, 0\n", " )\n", " df_shots['distance_to_goal'] = np.sqrt(((pitch_length_x - df_shots['x'])**2) + ((df_shots['y'] - (pitch_length_y/2))**2) )\n", " df_shots['distance_to_center'] = abs(df_shots['y'] - pitch_length_y/2)\n", " df_shots['angle'] = np.absolute(np.degrees(np.arctan((abs((pitch_length_y/2) - df_shots['y'])) / (pitch_length_x - df_shots['x']))))\n", "\n", " ### Convert data types \n", " df_shots['isHead'] = df_shots['isHead'].astype('int64')\n", "\n", "\n", " ## Data Preparation - for xG model\n", "\n", " ### Select Features of interest\n", " features_cols = ['distance_to_goal',\n", " 'angle',\n", " 'isFoot',\n", " 'isHead'\n", " ]\n", "\n", " ### Define Target\n", " target_col = ['isGoal']\n", "\n", " ###\n", " df_shots = df_shots[['event_id'] + features_cols + target_col]\n", "\n", "\n", " ## Assign Feature and Target to separate DataFrames and Series\n", " X = df_shots[features_cols]\n", " y = df_shots[target_col]\n", "\n", "\n", " ## Training of the logistic regression on the train set\n", " lr_model = LogisticRegression(random_state=42)\n", " lr_model.fit(X, y)\n", "\n", "\n", " ## Assign xG values i.e. Probability Predictions\n", "\n", " ### \n", " y_xg = lr_model.predict_proba(X)\n", "\n", " ### Convert the Probability Predictions array to a pandas DataFrame\n", " df_xg = pd.DataFrame(y_xg, columns = ['prob_no_goal', 'prob_goal'])\n", "\n", "\n", " ## Final DataFrame preparation\n", "\n", " ### Reset shots index\n", " df_shots = df_shots.reset_index(drop=True)\n", "\n", " ### Join the Probability Predictions back onto Shots DataFrame\n", " df_shots_xg = pd.merge(df_shots, df_xg, left_index=True, right_index=True, how='left')\n", "\n", " ### Select columns of interest\n", " df_shots_xg = df_shots_xg[['event_id', 'prob_goal']]\n", "\n", " ### Join the Shots DataFrame with the xG values back onto the original Events DataFrame\n", " df = pd.merge(df, df_shots_xg, left_on='event_id', right_on='event_id', how='left')\n", "\n", " ### Rename columns\n", " df = df.rename(columns={'prob_goal': 'xG'})\n", " \n", " \n", " ## Return DataFrame\n", " return df" ] }, { "cell_type": "code", "execution_count": 47, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "/opt/anaconda3/lib/python3.7/site-packages/sklearn/utils/validation.py:63: DataConversionWarning: A column-vector y was passed when a 1d array was expected. Please change the shape of y to (n_samples, ), for example using ravel().\n", " return f(*args, **kwargs)\n", "/opt/anaconda3/lib/python3.7/site-packages/sklearn/utils/validation.py:63: DataConversionWarning: A column-vector y was passed when a 1d array was expected. Please change the shape of y to (n_samples, ), for example using ravel().\n", " return f(*args, **kwargs)\n" ] } ], "source": [ "# Apply Create Multifeature Attributes function\n", "df_cry_lei_events = prepare_xg_df(df=df_cry_lei_events, pitch_length_x=100, pitch_length_y=100, lr_model=xg_model)\n", "df_cry_bri_events = prepare_xg_df(df=df_cry_bri_events, pitch_length_x=100, pitch_length_y=100, lr_model=xg_model)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "\n", "### 4.10. Determine xGChain and xGBuildup" ] }, { "cell_type": "code", "execution_count": 48, "metadata": {}, "outputs": [], "source": [ "def player_xgc(df):\n", " typemask = df['isShot'] == 1\n", " openplay = df['isRegularPlay'] == 1\n", " sameteam = df.team_name == df.possession_team_name\n", " df['OPS'] = np.where(typemask & openplay & sameteam,1,0)\n", " df['oneminusxG'] = 1.0 - df['shot_statsbomb_xg']\n", " aggdict = {'OPS':'sum','oneminusxG':np.prod}\n", " grouped = df[df.OPS==1].groupby(['team_name','possession']).agg(aggdict).reset_index()\n", " grouped['oneminusxG'] = 1.0 - grouped['oneminusxG']\n", " grouped.rename(columns={'oneminusxG':'xGCond'},inplace=True)\n", " grouped.drop(columns='OPS',inplace=True)\n", " df = df.merge(grouped,how='left')\n", " df['xGCond'].fillna(value=0,inplace=True)\n", " df['xGCond'] = np.where(df.type_name.isin(['Pass','Carry']),df.xGCond,0)\n", " groupdf = df.groupby(['player_name','possession']).agg({'xGCond':'mean'}).reset_index()\n", " return groupdf\n", "\n", "def player_xgb(match_id):\n", " gamedf = df[(df.match_id==match_id)&(df.period<=4)].reset_index(drop=True)\n", " typemask = gamedf.type_name == 'Shot'\n", " openplay = gamedf.shot_type_name == 'Open Play'\n", " sameteam = gamedf.team_name == gamedf.possession_team_name\n", " gamedf['OPS'] = np.where(typemask & openplay & sameteam,1,0)\n", " gamedf['oneminusxG'] = 1.0 - gamedf['shot_statsbomb_xg']\n", " aggdict = {'OPS':'sum','oneminusxG':np.prod}\n", " grouped = gamedf[gamedf.OPS==1].groupby(['team_name','possession']).agg(aggdict).reset_index()\n", " grouped['oneminusxG'] = 1.0 - grouped['oneminusxG']\n", " grouped.rename(columns={'oneminusxG':'xGCond'},inplace=True)\n", " grouped.drop(columns='OPS',inplace=True)\n", " gamedf = gamedf.merge(grouped,how='left')\n", " gamedf['xGCond'].fillna(value=0,inplace=True)\n", " gamedf['xGCond'] = np.where(gamedf.type_name.isin(['Pass','Carry']),gamedf.xGCond,0)\n", " gamedf.loc[(gamedf.pass_shot_assist==True)|(gamedf.pass_goal_assist==True),\n", " 'xGCond'] = 0\n", " groupdf = gamedf.groupby(['player_name','possession']).agg({'xGCond':'mean'}).reset_index()\n", " return groupdf" ] }, { "cell_type": "code", "execution_count": 49, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "\"\\nxgcdfs = []\\nxgbdfs = []\\n\\ndf = df_sb_events\\n\\nfor g in tqdm(df.match_id.unique(), desc='Reading Games'):\\n xgcdfs.append(player_xgc(g))\\n xgbdfs.append(player_xgb(g))\\n \\nxgcdf = pd.concat(xgcdfs, ignore_index=True)\\nxgbdf = pd.concat(xgbdfs, ignore_index=True)\\n\"" ] }, "execution_count": 49, "metadata": {}, "output_type": "execute_result" } ], "source": [ "\"\"\"\n", "xgcdfs = []\n", "xgbdfs = []\n", "\n", "df = df_sb_events\n", "\n", "for g in tqdm(df.match_id.unique(), desc='Reading Games'):\n", " xgcdfs.append(player_xgc(g))\n", " xgbdfs.append(player_xgb(g))\n", " \n", "xgcdf = pd.concat(xgcdfs, ignore_index=True)\n", "xgbdf = pd.concat(xgbdfs, ignore_index=True)\n", "\"\"\"" ] }, { "cell_type": "code", "execution_count": 50, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "\"\\nxgbdf.rename(columns={'xGCond':'xGBuildup'}, inplace=True)\\nxgcdf.rename(columns={'xGCond':'xGChain'}, inplace=True)\\n\\ndf_sb_events_grouped_xgbuildup = xgbdf.groupby('player_name').xGBuildup.sum().reset_index()\\ndf_sb_events_grouped_xgchain = xgcdf.groupby('player_name').xGChain.sum().reset_index()\\nlen(df_sb_events_grouped_xgbuildup), len(df_sb_events_grouped_xgchain)\\n\"" ] }, "execution_count": 50, "metadata": {}, "output_type": "execute_result" } ], "source": [ "\"\"\"\n", "xgbdf.rename(columns={'xGCond':'xGBuildup'}, inplace=True)\n", "xgcdf.rename(columns={'xGCond':'xGChain'}, inplace=True)\n", "\n", "df_sb_events_grouped_xgbuildup = xgbdf.groupby('player_name').xGBuildup.sum().reset_index()\n", "df_sb_events_grouped_xgchain = xgcdf.groupby('player_name').xGChain.sum().reset_index()\n", "len(df_sb_events_grouped_xgbuildup), len(df_sb_events_grouped_xgchain)\n", "\"\"\"" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Combine xGChain and xGBuildup" ] }, { "cell_type": "code", "execution_count": 51, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "\"\\ndf_sb_events_grouped_xg = df_sb_events_grouped_xgbuildup.merge(df_sb_events_grouped_xgchain, how='left')\\nlen(df_sb_events_grouped_xg)\\n\"" ] }, "execution_count": 51, "metadata": {}, "output_type": "execute_result" } ], "source": [ "\"\"\"\n", "df_sb_events_grouped_xg = df_sb_events_grouped_xgbuildup.merge(df_sb_events_grouped_xgchain, how='left')\n", "len(df_sb_events_grouped_xg)\n", "\"\"\"" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "\n", "### 4.11. Determine Expected Threat (xT) Values" ] }, { "cell_type": "code", "execution_count": 52, "metadata": {}, "outputs": [], "source": [ "# Define function to \n", "def determine_xt(df):\n", " \n", " \"\"\"\n", " Function to...\n", " \"\"\"\n", " \n", " ## Determine Expected Threat (xT)\n", " \n", " df['location_x'] = df['x']\n", " df['location_y'] = df['y'] \n", " df['endloc_x'] = df['PassEndX']\n", " df['endloc_y'] = df['PassEndY'] \n", "\n", "\n", " df = df[(df['isTouch'] == 1)].reset_index(drop=True)\n", "\n", "\n", " binx = [10*i for i in range(13)]\n", " biny = [10*i for i in range(9)]\n", "\n", " for cols in ['location_x','endloc_x']:\n", " s = pd.cut(df[cols], bins=binx, include_lowest=True)\n", " df['zone_'+cols] = pd.Series(data=pd.IntervalIndex(s).right, index = s.index)/10\n", "\n", " for cols in ['location_y','endloc_y']:\n", " s = pd.cut(df[cols], bins=biny, include_lowest=True)\n", " df['zone_'+cols] = pd.Series(data=pd.IntervalIndex(s).right, index = s.index)/10\n", "\n", " df['zone_start'] = df['zone_location_x'] + (df['zone_location_y']-1)*12\n", " df['zone_end'] = df['zone_endloc_x'] + (df['zone_endloc_y']-1)*12\n", "\n", " xtd = np.array([[0.00638303, 0.00779616, 0.00844854, 0.00977659, 0.01126267,\n", " 0.01248344, 0.01473596, 0.0174506 , 0.02122129, 0.02756312,\n", " 0.03485072, 0.0379259 ],\n", " [0.00750072, 0.00878589, 0.00942382, 0.0105949 , 0.01214719,\n", " 0.0138454 , 0.01611813, 0.01870347, 0.02401521, 0.02953272,\n", " 0.04066992, 0.04647721],\n", " [0.0088799 , 0.00977745, 0.01001304, 0.01110462, 0.01269174,\n", " 0.01429128, 0.01685596, 0.01935132, 0.0241224 , 0.02855202,\n", " 0.05491138, 0.06442595],\n", " [0.00941056, 0.01082722, 0.01016549, 0.01132376, 0.01262646,\n", " 0.01484598, 0.01689528, 0.0199707 , 0.02385149, 0.03511326,\n", " 0.10805102, 0.25745362],\n", " [0.00941056, 0.01082722, 0.01016549, 0.01132376, 0.01262646,\n", " 0.01484598, 0.01689528, 0.0199707 , 0.02385149, 0.03511326,\n", " 0.10805102, 0.25745362],\n", " [0.0088799 , 0.00977745, 0.01001304, 0.01110462, 0.01269174,\n", " 0.01429128, 0.01685596, 0.01935132, 0.0241224 , 0.02855202,\n", " 0.05491138, 0.06442595],\n", " [0.00750072, 0.00878589, 0.00942382, 0.0105949 , 0.01214719,\n", " 0.0138454 , 0.01611813, 0.01870347, 0.02401521, 0.02953272,\n", " 0.04066992, 0.04647721],\n", " [0.00638303, 0.00779616, 0.00844854, 0.00977659, 0.01126267,\n", " 0.01248344, 0.01473596, 0.0174506 , 0.02122129, 0.02756312,\n", " 0.03485072, 0.0379259 ]]).flatten()\n", "\n", " startXTdf = pd.DataFrame(data=xtd,columns=['xT_start'])\n", " startXTdf['zone_start'] = [i+1 for i in range(96)]\n", " endXTdf = pd.DataFrame(data=xtd,columns=['xT_end'])\n", " endXTdf['zone_end'] = [i+1 for i in range(96)]\n", "\n", " df = df.merge(startXTdf, on=['zone_start'], how='left')\n", " df = df.merge(endXTdf, on=['zone_end'], how='left')\n", " df['xT'] = df['xT_end'] - df['xT_start']\n", " \n", " \n", " ## Drop create columns not required\n", " df.drop(['location_x',\n", " 'location_y',\n", " 'endloc_x',\n", " 'endloc_y',\n", " 'zone_location_x',\n", " 'zone_endloc_x',\n", " 'zone_location_y',\n", " 'zone_endloc_y',\n", " 'zone_start',\n", " 'zone_end',\n", " 'xT_start',\n", " 'xT_end'\n", " ], axis=1, inplace=True)\n", " \n", " ## Return DataFrame\n", " return df" ] }, { "cell_type": "code", "execution_count": 53, "metadata": {}, "outputs": [], "source": [ "# Apply Create Multifeature Attributes function\n", "df_cry_lei_events = determine_xt(df_cry_lei_events)\n", "df_cry_bri_events = determine_xt(df_cry_bri_events)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "\n", "### 4.12. Unify Event DataFrames\n", ".." ] }, { "cell_type": "code", "execution_count": 54, "metadata": {}, "outputs": [], "source": [ "df_cry_bri_events['Match'] = '27/09/2021: Crystal Palace (1) vs. (1) Brighton & Hove Albion'\n", "df_cry_bri_events['Home Team'] = 'Crystal Palace'\n", "df_cry_bri_events['Away Team'] = 'Brighton & Hove Albion'\n", "\n", "df_cry_lei_events['Match'] = '03/10/2021: Crystal Palace (2) vs. (2) Leicester City'\n", "df_cry_lei_events['Home Team'] = 'Crystal Palace'\n", "df_cry_lei_events['Away Team'] = 'Leicester City'" ] }, { "cell_type": "code", "execution_count": 55, "metadata": {}, "outputs": [], "source": [ "df_cry_lei_events = df_cry_lei_events.loc[:,~df_cry_lei_events.columns.duplicated()]\n", "df_cry_bri_events = df_cry_bri_events.loc[:,~df_cry_bri_events.columns.duplicated()]" ] }, { "cell_type": "code", "execution_count": 56, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Index(['is1On1', 'isBoxDeepLeft', 'isCloseLeft', 'isFeet', 'isHighRight',\n", " 'isLeadingToGoal', 'isNotPastGoalLine', 'isParriedDanger',\n", " 'isTemp_Blocked'],\n", " dtype='object')" ] }, "execution_count": 56, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_cry_lei_events.columns.difference(df_cry_bri_events.columns)" ] }, { "cell_type": "code", "execution_count": 57, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Index(['isArgument', 'isCaptainChange', 'isCloseRight', 'isDeflection',\n", " 'isExcessiveCelebration', 'isFairPlay', 'isFantasyAssistTeam',\n", " 'isFantasyAssistType', 'isFantasyAssistedBy', 'isFreeKick', 'isGkHoof',\n", " 'isHighLeft', 'isMinutes', 'isReaching', 'isScored', 'isSixYardBlocked',\n", " 'isUnchallenged'],\n", " dtype='object')" ] }, "execution_count": 57, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_cry_bri_events.columns.difference(df_cry_lei_events.columns)" ] }, { "cell_type": "code", "execution_count": 58, "metadata": {}, "outputs": [], "source": [ "df_cry_bri_events.drop(['isArgument', 'isCaptainChange', 'isCloseRight', 'isDeflection',\n", " 'isExcessiveCelebration', 'isFairPlay', 'isFantasyAssistTeam',\n", " 'isFantasyAssistType', 'isFantasyAssistedBy', 'isFreeKick', 'isGkHoof',\n", " 'isHighLeft', 'isMinutes', 'isReaching', 'isScored', 'isSixYardBlocked',\n", " 'isUnchallenged'], axis=1, inplace=True)" ] }, { "cell_type": "code", "execution_count": 59, "metadata": {}, "outputs": [], "source": [ "df_cry_lei_events.drop(['is1On1', 'isBoxDeepLeft', 'isCloseLeft', 'isFeet', 'isHighRight',\n", " 'isLeadingToGoal', 'isNotPastGoalLine', 'isParriedDanger',\n", " 'isTemp_Blocked'], axis=1, inplace=True)" ] }, { "cell_type": "code", "execution_count": 60, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Index([], dtype='object')" ] }, "execution_count": 60, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_cry_lei_events.columns.difference(df_cry_bri_events.columns)" ] }, { "cell_type": "code", "execution_count": 61, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Index([], dtype='object')" ] }, "execution_count": 61, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_cry_bri_events.columns.difference(df_cry_lei_events.columns)" ] }, { "cell_type": "code", "execution_count": 62, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(1398, 209)" ] }, "execution_count": 62, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_cry_lei_events.shape" ] }, { "cell_type": "code", "execution_count": 63, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(1455, 209)" ] }, "execution_count": 63, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_cry_bri_events.shape" ] }, { "cell_type": "code", "execution_count": 64, "metadata": {}, "outputs": [], "source": [ "lst_events_dfs = [df_cry_bri_events, df_cry_lei_events]\n", "\n", "df_events_merged = pd.concat(lst_events_dfs)" ] }, { "cell_type": "code", "execution_count": 65, "metadata": {}, "outputs": [], "source": [ "df_events_merged.to_csv(os.path.join(data_dir_opta, 'engineered', 'F24', 'f24-eventdetails-merged.csv'), index=None, header=True)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "\n", "### 4.13. Aggregate Features\n", "Now that the features of interest have been created, the next stage is to aggregate these stats." ] }, { "cell_type": "code", "execution_count": 66, "metadata": {}, "outputs": [], "source": [ "# Define function to \n", "def create_aggregated_df(df):\n", " \n", " \"\"\"\n", " Function to...\n", " \"\"\"\n", " \n", " ### Drop duplicate columns\n", " df.columns.duplicated()\n", "\n", " \n", " ## Groupby and aggregate data\n", "\n", " ### Define dictionary to aggregate the data\n", " dict_agg = {'isPass': 'sum',\n", " 'isPassSuccessful': 'sum',\n", " 'isPassUnsuccessful': 'sum',\n", " 'isCrossOP': 'sum', \n", " 'isCrossOPSuccessful': 'sum',\n", " 'isCrossOPUnsuccessful': 'sum', \n", " 'isOffensivePass': 'sum', \n", " 'isOffensivePassWon': 'sum', \n", " 'isOffensivePassLost': 'sum', \n", " #'isAssist': 'sum', # breaking the code for some reason\n", " 'isKeyPass': 'sum', \n", " 'isBackwardPass': 'sum',\n", " 'isSidewayPass': 'sum',\n", " 'isLongPass': 'sum',\n", " 'isLongPassWon': 'sum',\n", " 'isLongPassLost': 'sum', \n", " #'isAerial': 'sum', # not working \n", " #'isAerialWon': 'sum', # not working\n", " #'isAerialLost': 'sum', # not working\n", " 'isGroundDuel': 'sum', \n", " 'isGroundDuelWon': 'sum', \n", " 'isGroundDuelLost': 'sum', \n", " 'isFreeKickTaken': 'sum',\n", " 'isFoul': 'sum', \n", " 'isFoulWon': 'sum', \n", " 'isFoulConceded': 'sum',\n", " 'isHandballConceded': 'sum',\n", " 'isCorner': 'sum',\n", " 'isCrossCorner': 'sum',\n", " 'isShortCorner': 'sum', \n", " 'isCornerIntoBoxSuccessful': 'sum',\n", " 'isCornerIntoBoxUnsuccessful': 'sum',\n", " 'isInterceptions': 'sum',\n", " 'isTackleWon': 'sum', \n", " 'isTackleLost': 'sum',\n", " 'isSave': 'sum', \n", " 'isSaveBlockOutfielder': 'sum', \n", " 'isClaim': 'sum',\n", " 'isClearanceLost': 'sum',\n", " 'isHeadedClearanceWon': 'sum', \n", " 'isHeadedClearanceLost': 'sum', \n", " 'isShot': 'sum',\n", " 'isShotOnTarget': 'sum',\n", " 'isShotOffTarget': 'sum',\n", " 'isGoal': 'sum',\n", " 'isGoalOP': 'sum',\n", " 'isGoalSetPiece': 'sum',\n", " 'isGoalPenalty': 'sum',\n", " 'isHeadedShotOnTarget': 'sum',\n", " 'isHeadedShot': 'sum',\n", " 'isHeadedShotOffTarget': 'sum',\n", " 'isShotBlockedByOutfielder': 'sum',\n", " 'isTouch': 'sum',\n", " 'isSuccessfulTakeOn': 'sum',\n", " 'isUnsuccessfulTakeOn': 'sum',\n", " 'isOverrun': 'sum',\n", " 'isFoulWon': 'sum',\n", " 'isFoulConceded': 'sum',\n", " 'isPenaltyConceded': 'sum',\n", " 'isYellowCard': 'sum',\n", " 'is2ndYellowCard': 'sum',\n", " 'isRedCard': 'sum',\n", " 'xG': 'sum',\n", " #'xGChain': 'sum',\n", " #'xGBuildup': 'sum',\n", " 'xT': 'sum'\n", " }\n", "\n", "\n", " ### Groupby by and aggregate the data\n", " df_grouped = (df\n", " .groupby('player_id')\n", " .agg(dict_agg)\n", " .reset_index()\n", " )\n", " \n", " \n", " ### Rename columns\n", " df_grouped = df_grouped.rename(columns={'isPass': 'Passes',\n", " 'isPassSuccessful': 'SuccessfulPasses',\n", " 'isPassUnsuccessful': 'UnsuccessfulPasses',\n", " 'isCrossOP': 'CrossesOP', \n", " 'isCrossOPSuccessful': 'SuccessfulCrossesOP',\n", " 'isCrossOPUnsuccessful': 'UnsuccessfulCrossesOP', \n", " 'isOffensivePass': 'OffensivePasses', \n", " 'isOffensivePassWon': 'SuccessfulOffensivePasses', \n", " 'isOffensivePassLost': 'UnsuccessfulOffensivePasses', \n", " #'isAssist': 'Assists', # breaking the code for some reason\n", " 'isKeyPass': 'KeyPasses', \n", " 'isBackwardPass': 'BackwardsPasses',\n", " 'isSidewayPass': 'SidewaysPasses',\n", " 'isLongPass': 'LongPasses',\n", " 'isLongPassWon': 'SuccessfulPassesWon',\n", " 'isLongPassLost': 'SuccessfulPassesLost', \n", " #'isAerial': 'Aerials', # not working \n", " #'isAerialWon': 'AerialsWon', # not working\n", " #'isAerialLost': 'AerialsLost', # not working\n", " 'isGroundDuel': 'GroundDuels', \n", " 'isGroundDuelWon': 'GroundDuelsWon', \n", " 'isGroundDuelLost': 'GroundDuelsLost', \n", " 'isFreeKickTaken': 'FreeKicksTaken',\n", " 'isFoul': 'Fouls', \n", " 'isFoulWon': 'FoulsWon', \n", " 'isFoulConceded': 'FoulsConceded',\n", " 'isHandballConceded': 'HandBallsConceded',\n", " 'isCorner': 'Corners',\n", " 'isCrossCorner': 'CrossCorners',\n", " 'isShortCorner': 'ShortCorners', \n", " 'isCornerIntoBoxSuccessful': 'SuccessfulCornersIntoBox',\n", " 'isCornerIntoBoxUnsuccessful': 'UnsuccessfulCornersIntoBox',\n", " 'isInterceptions': 'Interceptions',\n", " 'isTackleWon': 'TacklesWon', \n", " 'isTackleLost': 'TacklesLost',\n", " 'isSave': 'Saves', \n", " 'isSaveBlockOutfielder': 'SaveBlocks', \n", " 'isClaim': 'Claims',\n", " 'isClearanceLost': 'ClearancesLost',\n", " 'isHeadedClearanceWon': 'HeadedClearancesWon', \n", " 'isHeadedClearanceLost': 'HeadedClearancesLost', \n", " 'isShot': 'Shots',\n", " 'isShotOnTarget': 'ShotsOnTarget',\n", " 'isShotOffTarget': 'ShotsOffTarget',\n", " 'isGoal': 'Goals',\n", " 'isGoalOP': 'GoalsOP',\n", " 'isGoalSetPiece': 'GoalsSetPiece',\n", " 'isGoalPenalty': 'GoalsPenalties',\n", " 'isHeadedShotOnTarget': 'HeadedShotsOnTarget',\n", " 'isHeadedShot': 'HeadedShots',\n", " 'isHeadedShotOffTarget': 'HeadedShotsOffTarget',\n", " 'isShotBlockedByOutfielder': 'ShotsBlocked',\n", " 'isTouch': 'Touches',\n", " 'isSuccessfulTakeOn': 'SuccessfulTakeOns',\n", " 'isUnsuccessfulTakeOn': 'UnsuccessfulTakeOns',\n", " 'isOverrun': 'Overruns',\n", " 'isFoulWon': 'FoulsWon',\n", " 'isFoulConceded': 'FoulsConceded',\n", " 'isPenaltyConceded': 'PenaltiesConceded',\n", " 'isYellowCard': 'YellowCards',\n", " 'is2ndYellowCard': '2ndYellowCards',\n", " 'isRedCard': 'RedCards',\n", " 'xG': 'xG',\n", " #'xGChain': 'xGChain',\n", " #'xGBuildup': 'xGBuildup',\n", " 'xT': 'xT'\n", " }\n", " ) \n", " \n", " lst_cols = ['Passes',\n", " 'SuccessfulPasses',\n", " 'UnsuccessfulPasses',\n", " 'CrossesOP',\n", " 'SuccessfulCrossesOP',\n", " 'UnsuccessfulCrossesOP',\n", " 'OffensivePasses',\n", " 'SuccessfulOffensivePasses',\n", " 'UnsuccessfulOffensivePasses',\n", " 'KeyPasses',\n", " 'BackwardsPasses',\n", " 'SidewaysPasses',\n", " 'LongPasses',\n", " 'SuccessfulPassesWon',\n", " 'SuccessfulPassesLost',\n", " 'GroundDuels',\n", " 'GroundDuelsWon',\n", " 'GroundDuelsLost',\n", " 'FreeKicksTaken',\n", " 'Fouls',\n", " 'FoulsWon',\n", " 'FoulsConceded',\n", " 'HandBallsConceded',\n", " 'Corners',\n", " 'CrossCorners',\n", " 'ShortCorners',\n", " 'SuccessfulCornersIntoBox',\n", " 'UnsuccessfulCornersIntoBox',\n", " 'Interceptions',\n", " 'TacklesWon',\n", " 'TacklesLost',\n", " 'Saves',\n", " 'SaveBlocks',\n", " 'Claims',\n", " 'ClearancesLost',\n", " 'HeadedClearancesWon',\n", " 'HeadedClearancesLost',\n", " 'Shots',\n", " 'ShotsOnTarget',\n", " 'ShotsOffTarget',\n", " 'Goals',\n", " 'GoalsOP',\n", " 'GoalsSetPiece',\n", " 'GoalsPenalties',\n", " 'HeadedShotsOnTarget',\n", " 'HeadedShots',\n", " 'HeadedShotsOffTarget',\n", " 'ShotsBlocked',\n", " 'Touches',\n", " 'SuccessfulTakeOns',\n", " 'UnsuccessfulTakeOns',\n", " 'Overruns',\n", " 'PenaltiesConceded',\n", " 'YellowCards',\n", " '2ndYellowCards',\n", " 'RedCards',\n", " 'xG',\n", " 'xT'\n", " ]\n", " \n", " ### Rename columns\n", " df_grouped = df_grouped.rename(columns={'isPass': 'Passes',\n", " 'isPassSuccessful': 'SuccessfulPasses',\n", " 'isPassUnsuccessful': 'UnsuccessfulPasses',\n", " 'isCrossOP': 'CrossesOP', \n", " 'isCrossOPSuccessful': 'SuccessfulCrossesOP',\n", " 'isCrossOPUnsuccessful': 'UnsuccessfulCrossesOP', \n", " 'isOffensivePass': 'OffensivePasses', \n", " 'isOffensivePassWon': 'SuccessfulOffensivePasses', \n", " 'isOffensivePassLost': 'UnsuccessfulOffensivePasses', \n", " #'isAssist': 'Assists', # breaking the code for some reason\n", " 'isKeyPass': 'KeyPasses', \n", " 'isBackwardPass': 'BackwardsPasses',\n", " 'isSidewayPass': 'SidewaysPasses',\n", " 'isLongPass': 'LongPasses',\n", " 'isLongPassWon': 'SuccessfulPassesWon',\n", " 'isLongPassLost': 'SuccessfulPassesLost', \n", " #'isAerial': 'Aerials', # not working \n", " #'isAerialWon': 'AerialsWon', # not working\n", " #'isAerialLost': 'AerialsLost', # not working\n", " 'isGroundDuel': 'GroundDuels', \n", " 'isGroundDuelWon': 'GroundDuelsWon', \n", " 'isGroundDuelLost': 'GroundDuelsLost', \n", " 'isFreeKickTaken': 'FreeKicksTaken',\n", " 'isFoul': 'Fouls', \n", " 'isFoulWon': 'FoulsWon', \n", " 'isFoulConceded': 'FoulsConceded',\n", " 'isHandballConceded': 'HandBallsConceded',\n", " 'isCorner': 'Corners',\n", " 'isCrossCorner': 'CrossCorners',\n", " 'isShortCorner': 'ShortCorners', \n", " 'isCornerIntoBoxSuccessful': 'SuccessfulCornersIntoBox',\n", " 'isCornerIntoBoxUnsuccessful': 'UnsuccessfulCornersIntoBox',\n", " 'isInterceptions': 'Interceptions',\n", " 'isTackleWon': 'TacklesWon', \n", " 'isTackleLost': 'TacklesLost',\n", " 'isSave': 'Saves', \n", " 'isSaveBlockOutfielder': 'SaveBlocks', \n", " 'isClaim': 'Claims',\n", " 'isClearanceLost': 'ClearancesLost',\n", " 'isHeadedClearanceWon': 'HeadedClearancesWon', \n", " 'isHeadedClearanceLost': 'HeadedClearancesLost', \n", " 'isShot': 'Shots',\n", " 'isShotOnTarget': 'ShotsOnTarget',\n", " 'isShotOffTarget': 'ShotsOffTarget',\n", " 'isGoal': 'Goals',\n", " 'isGoalOP': 'GoalsOP',\n", " 'isGoalSetPiece': 'GoalsSetPiece',\n", " 'isGoalPenalty': 'GoalsPenalties',\n", " 'isHeadedShotOnTarget': 'HeadedShotsOnTarget',\n", " 'isHeadedShot': 'HeadedShots',\n", " 'isHeadedShotOffTarget': 'HeadedShotsOffTarget',\n", " 'isShotBlockedByOutfielder': 'ShotsBlocked',\n", " 'isTouch': 'Touches',\n", " 'isSuccessfulTakeOn': 'SuccessfulTakeOns',\n", " 'isUnsuccessfulTakeOn': 'UnsuccessfulTakeOns',\n", " 'isOverrun': 'Overruns',\n", " 'isFoulWon': 'FoulsWon',\n", " 'isFoulConceded': 'FoulsConceded',\n", " 'isPenaltyConceded': 'PenaltiesConceded',\n", " 'isYellowCard': 'YellowCards',\n", " 'is2ndYellowCard': '2ndYellowCards',\n", " 'isRedCard': 'RedCards',\n", " 'xG': 'xG',\n", " #'xGChain': 'xGChain',\n", " #'xGBuildup': 'xGBuildup',\n", " 'xT': 'xT'\n", " }\n", " ) \n", " \n", " ### Fill NULLs with 0\n", " df_grouped[lst_cols] = df_grouped[lst_cols].replace(np.nan, 0)\n", " \n", " ### Return DataFrame\n", " return df_grouped" ] }, { "cell_type": "code", "execution_count": 67, "metadata": {}, "outputs": [], "source": [ "# Apply Create Aggregated DataFrame function\n", "df_cry_lei_events_grouped = create_aggregated_df(df_cry_lei_events)\n", "df_cry_bri_events_grouped = create_aggregated_df(df_cry_bri_events)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "\n", "### 4.13. Add Player Information to Aggregated DataFrame" ] }, { "cell_type": "code", "execution_count": 68, "metadata": {}, "outputs": [], "source": [ "# Define function to \n", "def join_agg_player_dfs(df_players, df_grouped):\n", " \n", " \"\"\"\n", " Function to...\n", " \"\"\"\n", " \n", " ## Create features\n", " df_agg = pd.merge(df_players, df_grouped, left_on=['player_id'], right_on=['player_id'], how='left')\n", " \n", " ## Rename columns\n", " df_agg = df_agg.rename(columns={'Mins.Played': 'Mins'})\n", "\n", " ## Replace NULLs with 0\n", " df_agg = df_agg.replace(np.nan,0)\n", " \n", " ## Return DataFrame\n", " return df_agg" ] }, { "cell_type": "code", "execution_count": 69, "metadata": {}, "outputs": [], "source": [ "# Apply Create Multifeature Attributes function\n", "df_cry_lei_agg = join_agg_player_dfs(df_cry_lei_players, df_cry_lei_events_grouped)\n", "df_cry_bri_agg = join_agg_player_dfs(df_cry_bri_players, df_cry_bri_events_grouped)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "\n", "### 4.14. Create Percentage Completion Columns\n", "Now that the data has been aggregated, percentage completion column can be created." ] }, { "cell_type": "code", "execution_count": 70, "metadata": {}, "outputs": [], "source": [ "# Define function to \n", "def add_pct_completion_cols(df):\n", " \n", " \"\"\"\n", " Function to...\n", " \"\"\"\n", " \n", " ## Create Percentage Completion Columns\n", " #df['GroundDuelsSuccessPct'] = df['GroundDuelsWon'] / (df['GroundDuels'])\n", " df['PctPassFwd'] = df['OffensivePasses'] / df['Passes']\n", " df['PassSuccessPct'] = df['SuccessfulPasses'] / df['Passes'] \n", " #df['AerialSucPct'] = df['isAerialScs'] / df['isAerialTotal']\n", " df['CrossOPSuccessPct'] = df['SuccessfulCrossesOP'] / df['CrossesOP']\n", " \n", " ## Return DataFrame\n", " return df" ] }, { "cell_type": "code", "execution_count": 71, "metadata": {}, "outputs": [], "source": [ "# Apply Create Percentage Completion columns function\n", "df_cry_lei_agg = add_pct_completion_cols(df_cry_lei_agg)\n", "df_cry_bri_agg = add_pct_completion_cols(df_cry_bri_agg)" ] }, { "cell_type": "code", "execution_count": 72, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
indexplayer_idFirstNameLastNameFullNameFormation_PlacePositionJerseyNoStatusteam_HATimeOnTimeOffMinsMatchIDPassesSuccessfulPassesUnsuccessfulPassesCrossesOPSuccessfulCrossesOPUnsuccessfulCrossesOPOffensivePassesSuccessfulOffensivePassesUnsuccessfulOffensivePassesKeyPassesBackwardsPassesSidewaysPassesLongPassesSuccessfulPassesWonSuccessfulPassesLostGroundDuelsGroundDuelsWonGroundDuelsLostFreeKicksTakenFoulsFoulsWonFoulsConcededHandBallsConcededCornersCrossCornersShortCornersSuccessfulCornersIntoBoxUnsuccessfulCornersIntoBoxInterceptionsTacklesWonTacklesLostSavesSaveBlocksClaimsClearancesLostHeadedClearancesWonHeadedClearancesLostShotsShotsOnTargetShotsOffTargetGoalsGoalsOPGoalsSetPieceGoalsPenaltiesHeadedShotsOnTargetHeadedShotsHeadedShotsOffTargetShotsBlockedTouchesSuccessfulTakeOnsUnsuccessfulTakeOnsOverrunsPenaltiesConcededYellowCards2ndYellowCardsRedCardsxGxTPctPassFwdPassSuccessPctCrossOPSuccessPct
01101668JamieVardyJamie Vardy9Striker9Start00.096.096.0f22103344.04.00.01.00.01.01.01.00.02.03.00.00.00.00.00.00.00.00.03.01.02.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.03.02.01.01.01.00.00.00.01.01.01.012.00.00.00.00.00.00.00.00.3806480.0017270.251.00.0
12105666JackButlandJack Butland0Substitute1Sub10.00.00.0f22103340.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.0000000.000000NaNNaNNaN
23108413WillHughesWill Hughes0Substitute12Sub10.00.00.0f22103340.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.0000000.000000NaNNaNNaN
34111931Ricardo DomingosBarbosa PereiraRicardo Domingos Barbosa Pereira0Substitute21Sub00.00.00.0f22103340.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.0000000.000000NaNNaNNaN
45155569DanielAmarteyDaniel Amartey0Substitute18Sub00.00.00.0f22103340.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.0000000.000000NaNNaNNaN
\n", "
" ], "text/plain": [ " index player_id FirstName LastName \\\n", "0 1 101668 Jamie Vardy \n", "1 2 105666 Jack Butland \n", "2 3 108413 Will Hughes \n", "3 4 111931 Ricardo Domingos Barbosa Pereira \n", "4 5 155569 Daniel Amartey \n", "\n", " FullName Formation_Place Position JerseyNo \\\n", "0 Jamie Vardy 9 Striker 9 \n", "1 Jack Butland 0 Substitute 1 \n", "2 Will Hughes 0 Substitute 12 \n", "3 Ricardo Domingos Barbosa Pereira 0 Substitute 21 \n", "4 Daniel Amartey 0 Substitute 18 \n", "\n", " Status team_HA TimeOn TimeOff Mins MatchID Passes SuccessfulPasses \\\n", "0 Start 0 0.0 96.0 96.0 f2210334 4.0 4.0 \n", "1 Sub 1 0.0 0.0 0.0 f2210334 0.0 0.0 \n", "2 Sub 1 0.0 0.0 0.0 f2210334 0.0 0.0 \n", "3 Sub 0 0.0 0.0 0.0 f2210334 0.0 0.0 \n", "4 Sub 0 0.0 0.0 0.0 f2210334 0.0 0.0 \n", "\n", " UnsuccessfulPasses CrossesOP SuccessfulCrossesOP UnsuccessfulCrossesOP \\\n", "0 0.0 1.0 0.0 1.0 \n", "1 0.0 0.0 0.0 0.0 \n", "2 0.0 0.0 0.0 0.0 \n", "3 0.0 0.0 0.0 0.0 \n", "4 0.0 0.0 0.0 0.0 \n", "\n", " OffensivePasses SuccessfulOffensivePasses UnsuccessfulOffensivePasses \\\n", "0 1.0 1.0 0.0 \n", "1 0.0 0.0 0.0 \n", "2 0.0 0.0 0.0 \n", "3 0.0 0.0 0.0 \n", "4 0.0 0.0 0.0 \n", "\n", " KeyPasses BackwardsPasses SidewaysPasses LongPasses \\\n", "0 2.0 3.0 0.0 0.0 \n", "1 0.0 0.0 0.0 0.0 \n", "2 0.0 0.0 0.0 0.0 \n", "3 0.0 0.0 0.0 0.0 \n", "4 0.0 0.0 0.0 0.0 \n", "\n", " SuccessfulPassesWon SuccessfulPassesLost GroundDuels GroundDuelsWon \\\n", "0 0.0 0.0 0.0 0.0 \n", "1 0.0 0.0 0.0 0.0 \n", "2 0.0 0.0 0.0 0.0 \n", "3 0.0 0.0 0.0 0.0 \n", "4 0.0 0.0 0.0 0.0 \n", "\n", " GroundDuelsLost FreeKicksTaken Fouls FoulsWon FoulsConceded \\\n", "0 0.0 0.0 3.0 1.0 2.0 \n", "1 0.0 0.0 0.0 0.0 0.0 \n", "2 0.0 0.0 0.0 0.0 0.0 \n", "3 0.0 0.0 0.0 0.0 0.0 \n", "4 0.0 0.0 0.0 0.0 0.0 \n", "\n", " HandBallsConceded Corners CrossCorners ShortCorners \\\n", "0 0.0 0.0 0.0 0.0 \n", "1 0.0 0.0 0.0 0.0 \n", "2 0.0 0.0 0.0 0.0 \n", "3 0.0 0.0 0.0 0.0 \n", "4 0.0 0.0 0.0 0.0 \n", "\n", " SuccessfulCornersIntoBox UnsuccessfulCornersIntoBox Interceptions \\\n", "0 0.0 0.0 0.0 \n", "1 0.0 0.0 0.0 \n", "2 0.0 0.0 0.0 \n", "3 0.0 0.0 0.0 \n", "4 0.0 0.0 0.0 \n", "\n", " TacklesWon TacklesLost Saves SaveBlocks Claims ClearancesLost \\\n", "0 0.0 0.0 0.0 0.0 0.0 0.0 \n", "1 0.0 0.0 0.0 0.0 0.0 0.0 \n", "2 0.0 0.0 0.0 0.0 0.0 0.0 \n", "3 0.0 0.0 0.0 0.0 0.0 0.0 \n", "4 0.0 0.0 0.0 0.0 0.0 0.0 \n", "\n", " HeadedClearancesWon HeadedClearancesLost Shots ShotsOnTarget \\\n", "0 0.0 0.0 3.0 2.0 \n", "1 0.0 0.0 0.0 0.0 \n", "2 0.0 0.0 0.0 0.0 \n", "3 0.0 0.0 0.0 0.0 \n", "4 0.0 0.0 0.0 0.0 \n", "\n", " ShotsOffTarget Goals GoalsOP GoalsSetPiece GoalsPenalties \\\n", "0 1.0 1.0 1.0 0.0 0.0 \n", "1 0.0 0.0 0.0 0.0 0.0 \n", "2 0.0 0.0 0.0 0.0 0.0 \n", "3 0.0 0.0 0.0 0.0 0.0 \n", "4 0.0 0.0 0.0 0.0 0.0 \n", "\n", " HeadedShotsOnTarget HeadedShots HeadedShotsOffTarget ShotsBlocked \\\n", "0 0.0 1.0 1.0 1.0 \n", "1 0.0 0.0 0.0 0.0 \n", "2 0.0 0.0 0.0 0.0 \n", "3 0.0 0.0 0.0 0.0 \n", "4 0.0 0.0 0.0 0.0 \n", "\n", " Touches SuccessfulTakeOns UnsuccessfulTakeOns Overruns \\\n", "0 12.0 0.0 0.0 0.0 \n", "1 0.0 0.0 0.0 0.0 \n", "2 0.0 0.0 0.0 0.0 \n", "3 0.0 0.0 0.0 0.0 \n", "4 0.0 0.0 0.0 0.0 \n", "\n", " PenaltiesConceded YellowCards 2ndYellowCards RedCards xG \\\n", "0 0.0 0.0 0.0 0.0 0.380648 \n", "1 0.0 0.0 0.0 0.0 0.000000 \n", "2 0.0 0.0 0.0 0.0 0.000000 \n", "3 0.0 0.0 0.0 0.0 0.000000 \n", "4 0.0 0.0 0.0 0.0 0.000000 \n", "\n", " xT PctPassFwd PassSuccessPct CrossOPSuccessPct \n", "0 0.001727 0.25 1.0 0.0 \n", "1 0.000000 NaN NaN NaN \n", "2 0.000000 NaN NaN NaN \n", "3 0.000000 NaN NaN NaN \n", "4 0.000000 NaN NaN NaN " ] }, "execution_count": 72, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_cry_lei_agg.head(5)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Comments:\n", "- GroundDuels appears to be broken\n", "- CrossesOP looks weirdly low" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "\n", "### 4.15. Concatanate Event Data" ] }, { "cell_type": "code", "execution_count": 73, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
Unnamed: 0idevent_idtype_idperiod_idminsecteam_idoutcomexytimestamplast_modifiedversionplayer_idisKeyPassisAssistisLongBallGoalMouthYCoordinateisGoalMouthZCoordinateisThrowInisVolleyisKeeperThrowisGoalKickDirectionOfPlayisFoulTeamFormationTeamPlayerFormationisOwnPlayerPassEndXPassEndYDeletedEventTypeFormationSlotBlockedXCoordinateBlockedYCoordinateisHeadisDirectisIntentionalAssistisChippedisLayOffisLaunchisOutOfPlayisFlickOnisBoxCentreisParriedSafeisCollectedisStandingisDivingisOutOfBoxCentreisStoopingisHandsisBlockedCrossisPlayerNotVisibleCaptainisSwitchOfPlayTeamKitisGkKickFromHandsisCrossisRightFootedisGameEndisOtherBodyPartisOverrunLengthAngleisBigChanceisIndividualPlayisRegularPlayisInswingerisOutswingerisStraightResumeisOwnShotBlockedisPostMatchCompleteGkXCoordinateGkYCoordinateOppositeRelatedEventIdisBlockedPassisLowisSetPieceisGkStartisIndirectisFromCornerisOpenRoofAirHumidityAirPressureCelSiusDegreesisAttemptedTackleKickOffisDefensiveisOffensiveisOverArmisAssistedDetailedPositionIdisPositionSideIdisShovePushisShirtPullHoldingisHeadPassInvolvedisChecksCompleteisYellowCardisFirstTouchisThroughBallInjuryisTacticalPlayerPositionConditionsFieldPitchAttendanceFigureisFreeKickTakenInjuredPlayerIdRelatedEventIdZoneisEndTypeJerseyNumberisCornerTakenisBoxRightisBoxLeftPlayersCaughtOffsideisLeftFootedisLeftisHighisRightisLowLeftisLowCentreisLowRightisBlockedisHighClaimisDefBlockevent_nameindexFirstNameLastNameFullNameFormation_PlacePositionJerseyNoStatusteam_HATimeOnTimeOffMins.PlayedMatchIDisAerialFoulisHandisOwnGoalisPenaltyisSecondYellowisRedCardisPassisPassSuccessfulisPassUnsuccessfulisCrossOPisCrossOPSuccessfulisCrossOPUnsuccessfulisOffensivePassisOffensivePassWonisOffensivePassLostisBackwardPassisSidewayPassisLongPassisLongPassWonisLongPassLostisAerialisAerialWonisAerialLostisGroundDuelisGroundDuelWonisGroundDuelLostisFoulWonisFoulConcededisHandballConcededisCornerisCrossCornerisShortCornerisCornerIntoBoxSuccessfulisCornerIntoBoxUnsuccessfulisInterceptionsisTackleWonisTackleLostisSaveisSaveBlockOutfielderisClaimisClearanceLostisHeadedClearanceWonisHeadedClearanceLostisShotisShotOnTargetisShotOffTargetisShotOPisShotSetPieceisShotPenaltyisHeadedShotisHeadedShotOnTargetisHeadedShotOffTargetisGoalisGoalOPisGoalSetPieceisGoalPenaltyisShotBlockedByOutfielderisTouchisSuccessfulTakeOnisUnsuccessfulTakeOnisPenaltyConcededis2ndYellowCardxGxTMatchHome TeamAway Team
0523386962993110031150.250.02021-10-03T14:00:24.5762021-10-03T22:27:55163329647495650471.0000.0NaN0.00.00.00.00.0NaN0NaNNaN0.033.149.0NaNNaNNaNNaN0.00.00.00.00.00.00.00.00.00.00.01.00.00.00.00.00.00.0NaN0.0NaN0.00.00.00.00.0018.03.20.00.00.00.00.00.0NaN0.00.0NaNNaNNaN0.00.00.00.00.00.00.0NaNNaNNaN0.0S0.00.00.00.0NaN0.00.00.00.0NaN0.000.00.0NaN0.0NaNNaNNaNNaN0NaNNaNBack0.0NaN0.00.00.0NaN0.00.00.00.00.00.00.00.00.00.0isPass28.0JamesMcArthurJames McArthur8.0Midfielder18.0Start1.00.096.096.0f221033400000011000000010000000000000000000000000000000000000000010000NaN-0.00352203/10/2021: Crystal Palace (2) vs. (2) Leicest...Crystal PalaceLeicester City
1623386963194110231132.949.02021-10-03T14:00:26.9982021-10-03T22:28:021633296482303174874.0000.0NaN0.00.00.00.00.0NaN0NaNNaN0.035.369.4NaNNaNNaNNaN0.00.00.00.00.00.00.00.00.00.00.01.00.00.00.00.00.00.0NaN0.0NaN0.00.00.00.00.0014.11.40.00.00.00.00.00.0NaN0.00.0NaNNaNNaN0.00.00.00.00.00.00.0NaNNaNNaN0.0NaN0.00.00.00.0NaN0.00.00.00.0NaN0.000.00.0NaN0.0NaNNaNNaNNaN0NaNNaNBack0.0NaN0.00.00.0NaN0.00.00.00.00.00.00.00.00.00.0isPass11.0JoachimAndersenJoachim Andersen5.0Defender16.0Start1.00.096.096.0f221033400000011000011000000000000000000000000000000000000000000010000NaN-0.00072903/10/2021: Crystal Palace (2) vs. (2) Leicest...Crystal PalaceLeicester City
2723386964295110431136.471.02021-10-03T14:00:29.1672021-10-03T22:28:051633296485941209036.0000.0NaN0.00.00.00.00.0NaN0NaNNaN0.042.489.0NaNNaNNaNNaN0.00.00.00.00.00.00.00.00.00.00.01.00.00.00.00.00.00.0NaN0.0NaN0.00.00.00.00.0013.81.10.00.00.00.00.00.0NaN0.00.0NaNNaNNaN0.00.00.00.00.00.00.0NaNNaNNaN0.0NaN0.00.00.00.0NaN0.00.00.00.0NaN0.000.00.0NaN0.0NaNNaNNaNNaN0NaNNaNBack0.0NaN0.00.00.0NaN0.00.00.00.00.00.00.00.00.00.0isPass16.0MarcGuéhiMarc Guéhi6.0Defender6.0Start1.00.096.096.0f221033400000011000011000000000000000000000000000000000000000000010000NaNNaN03/10/2021: Crystal Palace (2) vs. (2) Leicest...Crystal PalaceLeicester City
3923386964676110931045.876.62021-10-03T14:00:34.0922021-10-03T22:28:121633296492605244723.0000.0NaN0.00.00.00.00.0NaN0NaNNaN0.053.975.4NaNNaNNaNNaN0.00.00.00.00.00.00.00.00.00.00.01.00.00.00.00.00.00.0NaN0.0NaN0.00.00.00.00.008.56.20.00.00.00.00.00.0NaN0.00.0NaNNaNNaN0.00.00.00.00.00.00.0NaNNaNNaN0.0NaN0.00.00.00.0NaN0.00.00.00.0NaN0.000.00.0NaN0.0NaNNaNNaNNaN0NaNNaNCenter0.0NaN0.00.00.0NaN0.00.00.00.00.00.00.00.00.00.0isPass22.0TyrickMitchellTyrick Mitchell3.0Defender3.0Start1.00.096.096.0f221033400000010100010100000000000000000000000000000000000000000010000NaN0.00122103/10/2021: Crystal Palace (2) vs. (2) Leicest...Crystal PalaceLeicester City
410233869660141101113046.027.82021-10-03T14:00:36.2682021-10-03T22:28:211633296501357197469.0001.0NaN0.00.00.00.00.0NaN0NaNNaN0.084.30.0NaNNaNNaNNaN0.00.00.00.00.00.00.00.00.00.00.01.00.00.00.00.00.00.0NaN0.0NaN0.00.00.00.00.0044.65.80.00.00.00.00.00.0NaN0.00.0NaNNaNNaN0.00.00.00.00.00.00.0NaNNaNNaN0.0NaN0.00.00.00.0NaN0.00.00.00.0NaN0.000.00.0NaN0.0NaNNaNNaNNaN0NaNNaNRight0.0NaN0.00.00.0NaN0.00.00.00.00.00.00.00.00.00.0isPass13.0HamzaChoudhuryHamza Choudhury4.0Midfielder20.0Start0.00.060.060.0f221033400000010100010100101000000000000000000000000000000000000010000NaN0.00853003/10/2021: Crystal Palace (2) vs. (2) Leicest...Crystal PalaceLeicester City
\n", "
" ], "text/plain": [ " Unnamed: 0 id event_id type_id period_id min sec team_id \\\n", "0 5 2338696299 3 1 1 0 0 31 \n", "1 6 2338696319 4 1 1 0 2 31 \n", "2 7 2338696429 5 1 1 0 4 31 \n", "3 9 2338696467 6 1 1 0 9 31 \n", "4 10 2338696601 4 1 1 0 11 13 \n", "\n", " outcome x y timestamp last_modified \\\n", "0 1 50.2 50.0 2021-10-03T14:00:24.576 2021-10-03T22:27:55 \n", "1 1 32.9 49.0 2021-10-03T14:00:26.998 2021-10-03T22:28:02 \n", "2 1 36.4 71.0 2021-10-03T14:00:29.167 2021-10-03T22:28:05 \n", "3 0 45.8 76.6 2021-10-03T14:00:34.092 2021-10-03T22:28:12 \n", "4 0 46.0 27.8 2021-10-03T14:00:36.268 2021-10-03T22:28:21 \n", "\n", " version player_id isKeyPass isAssist isLongBall \\\n", "0 1633296474956 50471.0 0 0 0.0 \n", "1 1633296482303 174874.0 0 0 0.0 \n", "2 1633296485941 209036.0 0 0 0.0 \n", "3 1633296492605 244723.0 0 0 0.0 \n", "4 1633296501357 197469.0 0 0 1.0 \n", "\n", " GoalMouthYCoordinate isGoalMouthZCoordinate isThrowIn isVolley \\\n", "0 NaN 0.0 0.0 0.0 \n", "1 NaN 0.0 0.0 0.0 \n", "2 NaN 0.0 0.0 0.0 \n", "3 NaN 0.0 0.0 0.0 \n", "4 NaN 0.0 0.0 0.0 \n", "\n", " isKeeperThrow isGoalKick DirectionOfPlay isFoul TeamFormation \\\n", "0 0.0 0.0 NaN 0 NaN \n", "1 0.0 0.0 NaN 0 NaN \n", "2 0.0 0.0 NaN 0 NaN \n", "3 0.0 0.0 NaN 0 NaN \n", "4 0.0 0.0 NaN 0 NaN \n", "\n", " TeamPlayerFormation isOwnPlayer PassEndX PassEndY DeletedEventType \\\n", "0 NaN 0.0 33.1 49.0 NaN \n", "1 NaN 0.0 35.3 69.4 NaN \n", "2 NaN 0.0 42.4 89.0 NaN \n", "3 NaN 0.0 53.9 75.4 NaN \n", "4 NaN 0.0 84.3 0.0 NaN \n", "\n", " FormationSlot BlockedXCoordinate BlockedYCoordinate isHead isDirect \\\n", "0 NaN NaN NaN 0.0 0.0 \n", "1 NaN NaN NaN 0.0 0.0 \n", "2 NaN NaN NaN 0.0 0.0 \n", "3 NaN NaN NaN 0.0 0.0 \n", "4 NaN NaN NaN 0.0 0.0 \n", "\n", " isIntentionalAssist isChipped isLayOff isLaunch isOutOfPlay isFlickOn \\\n", "0 0.0 0.0 0.0 0.0 0.0 0.0 \n", "1 0.0 0.0 0.0 0.0 0.0 0.0 \n", "2 0.0 0.0 0.0 0.0 0.0 0.0 \n", "3 0.0 0.0 0.0 0.0 0.0 0.0 \n", "4 0.0 0.0 0.0 0.0 0.0 0.0 \n", "\n", " isBoxCentre isParriedSafe isCollected isStanding isDiving \\\n", "0 0.0 0.0 0.0 1.0 0.0 \n", "1 0.0 0.0 0.0 1.0 0.0 \n", "2 0.0 0.0 0.0 1.0 0.0 \n", "3 0.0 0.0 0.0 1.0 0.0 \n", "4 0.0 0.0 0.0 1.0 0.0 \n", "\n", " isOutOfBoxCentre isStooping isHands isBlockedCross isPlayerNotVisible \\\n", "0 0.0 0.0 0.0 0.0 0.0 \n", "1 0.0 0.0 0.0 0.0 0.0 \n", "2 0.0 0.0 0.0 0.0 0.0 \n", "3 0.0 0.0 0.0 0.0 0.0 \n", "4 0.0 0.0 0.0 0.0 0.0 \n", "\n", " Captain isSwitchOfPlay TeamKit isGkKickFromHands isCross \\\n", "0 NaN 0.0 NaN 0.0 0.0 \n", "1 NaN 0.0 NaN 0.0 0.0 \n", "2 NaN 0.0 NaN 0.0 0.0 \n", "3 NaN 0.0 NaN 0.0 0.0 \n", "4 NaN 0.0 NaN 0.0 0.0 \n", "\n", " isRightFooted isGameEnd isOtherBodyPart isOverrun Length Angle \\\n", "0 0.0 0.0 0.0 0 18.0 3.2 \n", "1 0.0 0.0 0.0 0 14.1 1.4 \n", "2 0.0 0.0 0.0 0 13.8 1.1 \n", "3 0.0 0.0 0.0 0 8.5 6.2 \n", "4 0.0 0.0 0.0 0 44.6 5.8 \n", "\n", " isBigChance isIndividualPlay isRegularPlay isInswinger isOutswinger \\\n", "0 0.0 0.0 0.0 0.0 0.0 \n", "1 0.0 0.0 0.0 0.0 0.0 \n", "2 0.0 0.0 0.0 0.0 0.0 \n", "3 0.0 0.0 0.0 0.0 0.0 \n", "4 0.0 0.0 0.0 0.0 0.0 \n", "\n", " isStraight Resume isOwnShotBlocked isPostMatchComplete GkXCoordinate \\\n", "0 0.0 NaN 0.0 0.0 NaN \n", "1 0.0 NaN 0.0 0.0 NaN \n", "2 0.0 NaN 0.0 0.0 NaN \n", "3 0.0 NaN 0.0 0.0 NaN \n", "4 0.0 NaN 0.0 0.0 NaN \n", "\n", " GkYCoordinate OppositeRelatedEventId isBlockedPass isLow isSetPiece \\\n", "0 NaN NaN 0.0 0.0 0.0 \n", "1 NaN NaN 0.0 0.0 0.0 \n", "2 NaN NaN 0.0 0.0 0.0 \n", "3 NaN NaN 0.0 0.0 0.0 \n", "4 NaN NaN 0.0 0.0 0.0 \n", "\n", " isGkStart isIndirect isFromCorner isOpenRoof AirHumidity AirPressure \\\n", "0 0.0 0.0 0.0 0.0 NaN NaN \n", "1 0.0 0.0 0.0 0.0 NaN NaN \n", "2 0.0 0.0 0.0 0.0 NaN NaN \n", "3 0.0 0.0 0.0 0.0 NaN NaN \n", "4 0.0 0.0 0.0 0.0 NaN NaN \n", "\n", " CelSiusDegrees isAttemptedTackle KickOff isDefensive isOffensive \\\n", "0 NaN 0.0 S 0.0 0.0 \n", "1 NaN 0.0 NaN 0.0 0.0 \n", "2 NaN 0.0 NaN 0.0 0.0 \n", "3 NaN 0.0 NaN 0.0 0.0 \n", "4 NaN 0.0 NaN 0.0 0.0 \n", "\n", " isOverArm isAssisted DetailedPositionId isPositionSideId isShovePush \\\n", "0 0.0 0.0 NaN 0.0 0.0 \n", "1 0.0 0.0 NaN 0.0 0.0 \n", "2 0.0 0.0 NaN 0.0 0.0 \n", "3 0.0 0.0 NaN 0.0 0.0 \n", "4 0.0 0.0 NaN 0.0 0.0 \n", "\n", " isShirtPullHolding isHeadPass Involved isChecksComplete isYellowCard \\\n", "0 0.0 0.0 NaN 0.0 0 \n", "1 0.0 0.0 NaN 0.0 0 \n", "2 0.0 0.0 NaN 0.0 0 \n", "3 0.0 0.0 NaN 0.0 0 \n", "4 0.0 0.0 NaN 0.0 0 \n", "\n", " isFirstTouch isThroughBall Injury isTactical PlayerPosition Conditions \\\n", "0 0.0 0.0 NaN 0.0 NaN NaN \n", "1 0.0 0.0 NaN 0.0 NaN NaN \n", "2 0.0 0.0 NaN 0.0 NaN NaN \n", "3 0.0 0.0 NaN 0.0 NaN NaN \n", "4 0.0 0.0 NaN 0.0 NaN NaN \n", "\n", " FieldPitch AttendanceFigure isFreeKickTaken InjuredPlayerId \\\n", "0 NaN NaN 0 NaN \n", "1 NaN NaN 0 NaN \n", "2 NaN NaN 0 NaN \n", "3 NaN NaN 0 NaN \n", "4 NaN NaN 0 NaN \n", "\n", " RelatedEventId Zone isEndType JerseyNumber isCornerTaken isBoxRight \\\n", "0 NaN Back 0.0 NaN 0.0 0.0 \n", "1 NaN Back 0.0 NaN 0.0 0.0 \n", "2 NaN Back 0.0 NaN 0.0 0.0 \n", "3 NaN Center 0.0 NaN 0.0 0.0 \n", "4 NaN Right 0.0 NaN 0.0 0.0 \n", "\n", " isBoxLeft PlayersCaughtOffside isLeftFooted isLeft isHigh isRight \\\n", "0 0.0 NaN 0.0 0.0 0.0 0.0 \n", "1 0.0 NaN 0.0 0.0 0.0 0.0 \n", "2 0.0 NaN 0.0 0.0 0.0 0.0 \n", "3 0.0 NaN 0.0 0.0 0.0 0.0 \n", "4 0.0 NaN 0.0 0.0 0.0 0.0 \n", "\n", " isLowLeft isLowCentre isLowRight isBlocked isHighClaim isDefBlock \\\n", "0 0.0 0.0 0.0 0.0 0.0 0.0 \n", "1 0.0 0.0 0.0 0.0 0.0 0.0 \n", "2 0.0 0.0 0.0 0.0 0.0 0.0 \n", "3 0.0 0.0 0.0 0.0 0.0 0.0 \n", "4 0.0 0.0 0.0 0.0 0.0 0.0 \n", "\n", " event_name index FirstName LastName FullName Formation_Place \\\n", "0 isPass 28.0 James McArthur James McArthur 8.0 \n", "1 isPass 11.0 Joachim Andersen Joachim Andersen 5.0 \n", "2 isPass 16.0 Marc Guéhi Marc Guéhi 6.0 \n", "3 isPass 22.0 Tyrick Mitchell Tyrick Mitchell 3.0 \n", "4 isPass 13.0 Hamza Choudhury Hamza Choudhury 4.0 \n", "\n", " Position JerseyNo Status team_HA TimeOn TimeOff Mins.Played \\\n", "0 Midfielder 18.0 Start 1.0 0.0 96.0 96.0 \n", "1 Defender 16.0 Start 1.0 0.0 96.0 96.0 \n", "2 Defender 6.0 Start 1.0 0.0 96.0 96.0 \n", "3 Defender 3.0 Start 1.0 0.0 96.0 96.0 \n", "4 Midfielder 20.0 Start 0.0 0.0 60.0 60.0 \n", "\n", " MatchID isAerialFoul isHand isOwnGoal isPenalty isSecondYellow \\\n", "0 f2210334 0 0 0 0 0 \n", "1 f2210334 0 0 0 0 0 \n", "2 f2210334 0 0 0 0 0 \n", "3 f2210334 0 0 0 0 0 \n", "4 f2210334 0 0 0 0 0 \n", "\n", " isRedCard isPass isPassSuccessful isPassUnsuccessful isCrossOP \\\n", "0 0 1 1 0 0 \n", "1 0 1 1 0 0 \n", "2 0 1 1 0 0 \n", "3 0 1 0 1 0 \n", "4 0 1 0 1 0 \n", "\n", " isCrossOPSuccessful isCrossOPUnsuccessful isOffensivePass \\\n", "0 0 0 0 \n", "1 0 0 1 \n", "2 0 0 1 \n", "3 0 0 1 \n", "4 0 0 1 \n", "\n", " isOffensivePassWon isOffensivePassLost isBackwardPass isSidewayPass \\\n", "0 0 0 1 0 \n", "1 1 0 0 0 \n", "2 1 0 0 0 \n", "3 0 1 0 0 \n", "4 0 1 0 0 \n", "\n", " isLongPass isLongPassWon isLongPassLost isAerial isAerialWon \\\n", "0 0 0 0 0 0 \n", "1 0 0 0 0 0 \n", "2 0 0 0 0 0 \n", "3 0 0 0 0 0 \n", "4 1 0 1 0 0 \n", "\n", " isAerialLost isGroundDuel isGroundDuelWon isGroundDuelLost isFoulWon \\\n", "0 0 0 0 0 0 \n", "1 0 0 0 0 0 \n", "2 0 0 0 0 0 \n", "3 0 0 0 0 0 \n", "4 0 0 0 0 0 \n", "\n", " isFoulConceded isHandballConceded isCorner isCrossCorner isShortCorner \\\n", "0 0 0 0 0 0 \n", "1 0 0 0 0 0 \n", "2 0 0 0 0 0 \n", "3 0 0 0 0 0 \n", "4 0 0 0 0 0 \n", "\n", " isCornerIntoBoxSuccessful isCornerIntoBoxUnsuccessful isInterceptions \\\n", "0 0 0 0 \n", "1 0 0 0 \n", "2 0 0 0 \n", "3 0 0 0 \n", "4 0 0 0 \n", "\n", " isTackleWon isTackleLost isSave isSaveBlockOutfielder isClaim \\\n", "0 0 0 0 0 0 \n", "1 0 0 0 0 0 \n", "2 0 0 0 0 0 \n", "3 0 0 0 0 0 \n", "4 0 0 0 0 0 \n", "\n", " isClearanceLost isHeadedClearanceWon isHeadedClearanceLost isShot \\\n", "0 0 0 0 0 \n", "1 0 0 0 0 \n", "2 0 0 0 0 \n", "3 0 0 0 0 \n", "4 0 0 0 0 \n", "\n", " isShotOnTarget isShotOffTarget isShotOP isShotSetPiece isShotPenalty \\\n", "0 0 0 0 0 0 \n", "1 0 0 0 0 0 \n", "2 0 0 0 0 0 \n", "3 0 0 0 0 0 \n", "4 0 0 0 0 0 \n", "\n", " isHeadedShot isHeadedShotOnTarget isHeadedShotOffTarget isGoal \\\n", "0 0 0 0 0 \n", "1 0 0 0 0 \n", "2 0 0 0 0 \n", "3 0 0 0 0 \n", "4 0 0 0 0 \n", "\n", " isGoalOP isGoalSetPiece isGoalPenalty isShotBlockedByOutfielder \\\n", "0 0 0 0 0 \n", "1 0 0 0 0 \n", "2 0 0 0 0 \n", "3 0 0 0 0 \n", "4 0 0 0 0 \n", "\n", " isTouch isSuccessfulTakeOn isUnsuccessfulTakeOn isPenaltyConceded \\\n", "0 1 0 0 0 \n", "1 1 0 0 0 \n", "2 1 0 0 0 \n", "3 1 0 0 0 \n", "4 1 0 0 0 \n", "\n", " is2ndYellowCard xG xT \\\n", "0 0 NaN -0.003522 \n", "1 0 NaN -0.000729 \n", "2 0 NaN NaN \n", "3 0 NaN 0.001221 \n", "4 0 NaN 0.008530 \n", "\n", " Match Home Team \\\n", "0 03/10/2021: Crystal Palace (2) vs. (2) Leicest... Crystal Palace \n", "1 03/10/2021: Crystal Palace (2) vs. (2) Leicest... Crystal Palace \n", "2 03/10/2021: Crystal Palace (2) vs. (2) Leicest... Crystal Palace \n", "3 03/10/2021: Crystal Palace (2) vs. (2) Leicest... Crystal Palace \n", "4 03/10/2021: Crystal Palace (2) vs. (2) Leicest... Crystal Palace \n", "\n", " Away Team \n", "0 Leicester City \n", "1 Leicester City \n", "2 Leicester City \n", "3 Leicester City \n", "4 Leicester City " ] }, "execution_count": 73, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_cry_lei_events.head()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "\n", "### 4.16. Create Formations Dataset" ] }, { "cell_type": "code", "execution_count": 74, "metadata": {}, "outputs": [], "source": [ "# Define function to \n", "def formation(df_game, df_players):\n", " \n", " \"\"\"\n", " Function to...\n", " \"\"\"\n", " \n", " ## Join game and players DataFrames\n", " df_formation = pd.merge(df_game, df_players, left_on=['MatchID', 'team_HA'], right_on=['MatchID', 'team_HA'], how='left')\n", " \n", " ## Drop columns\n", " df_formation = df_formation.drop(columns=['index_x', 'index_y'])\n", "\n", " ## Return DataFrame\n", " return df_formation" ] }, { "cell_type": "code", "execution_count": 75, "metadata": {}, "outputs": [], "source": [ "df_cry_bri_formation = formation(df_cry_bri_game, df_cry_bri_players)\n", "df_cry_lei_formation = formation(df_cry_lei_game, df_cry_lei_players)" ] }, { "cell_type": "code", "execution_count": 76, "metadata": {}, "outputs": [], "source": [ "df_cry_bri_formation.to_csv(os.path.join(data_dir_opta, 'engineered', 'F7', 'srml-8-2021-f2210324-matchresults-formations.csv'), index=None, header=True)\n", "df_cry_lei_formation.to_csv(os.path.join(data_dir_opta, 'engineered', 'F7', 'srml-8-2021-f2210334-matchresults-formations.csv'), index=None, header=True)" ] }, { "cell_type": "code", "execution_count": 77, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
x
median
period_idLastName
1Andersen32.60
Ayew66.00
Barnes54.90
Bertrand37.15
Castagne40.60
Choudhury51.30
Gallagher55.60
Guaita12.40
Guéhi27.80
Iheanacho69.70
Lookman53.80
McArthur52.95
Milivojevic46.50
Mitchell44.60
Schmeichel6.60
Söyüncü30.10
Tielemans46.90
Vardy79.15
Vestergaard33.60
Ward53.10
Zaha59.10
Édouard67.70
2Albrighton33.95
Andersen32.40
Ayew68.15
Barnes41.15
Benteke62.40
Bertrand52.85
Castagne30.10
Choudhury34.80
Gallagher66.55
Guaita4.50
Guéhi36.90
Iheanacho53.90
Lookman58.20
Maddison63.40
McArthur58.15
Milivojevic53.80
Mitchell56.40
Olise67.00
Schlupp88.70
Schmeichel4.60
Soumaré34.60
Söyüncü26.80
Tielemans42.30
Vardy72.60
Vestergaard20.90
Ward39.35
Zaha67.95
Édouard76.40
\n", "
" ], "text/plain": [ " x\n", " median\n", "period_id LastName \n", "1 Andersen 32.60\n", " Ayew 66.00\n", " Barnes 54.90\n", " Bertrand 37.15\n", " Castagne 40.60\n", " Choudhury 51.30\n", " Gallagher 55.60\n", " Guaita 12.40\n", " Guéhi 27.80\n", " Iheanacho 69.70\n", " Lookman 53.80\n", " McArthur 52.95\n", " Milivojevic 46.50\n", " Mitchell 44.60\n", " Schmeichel 6.60\n", " Söyüncü 30.10\n", " Tielemans 46.90\n", " Vardy 79.15\n", " Vestergaard 33.60\n", " Ward 53.10\n", " Zaha 59.10\n", " Édouard 67.70\n", "2 Albrighton 33.95\n", " Andersen 32.40\n", " Ayew 68.15\n", " Barnes 41.15\n", " Benteke 62.40\n", " Bertrand 52.85\n", " Castagne 30.10\n", " Choudhury 34.80\n", " Gallagher 66.55\n", " Guaita 4.50\n", " Guéhi 36.90\n", " Iheanacho 53.90\n", " Lookman 58.20\n", " Maddison 63.40\n", " McArthur 58.15\n", " Milivojevic 53.80\n", " Mitchell 56.40\n", " Olise 67.00\n", " Schlupp 88.70\n", " Schmeichel 4.60\n", " Soumaré 34.60\n", " Söyüncü 26.80\n", " Tielemans 42.30\n", " Vardy 72.60\n", " Vestergaard 20.90\n", " Ward 39.35\n", " Zaha 67.95\n", " Édouard 76.40" ] }, "execution_count": 77, "metadata": {}, "output_type": "execute_result" } ], "source": [ "#\n", "\n", "##\n", "(df_cry_lei_events\n", " .groupby(['period_id',\n", " 'LastName',\n", " ])\n", " .agg({'x': ['median']\n", " })\n", " )" ] }, { "cell_type": "code", "execution_count": 78, "metadata": {}, "outputs": [], "source": [ "# Flip X axis for 2nd half\n", "#df_events['x'] = np.where(df_events['period_id'] == '2', 100 - df_events['x'], df_events['x'])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "\n", "### 4.17. Create Passing Matrix DataFrame" ] }, { "cell_type": "code", "execution_count": 79, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
Unnamed: 0idevent_idtype_idperiod_idminsecteam_idoutcomexytimestamplast_modifiedversionplayer_idisKeyPassisAssistisLongBallGoalMouthYCoordinateisGoalMouthZCoordinateisThrowInisVolleyisKeeperThrowisGoalKickDirectionOfPlayisFoulTeamFormationTeamPlayerFormationisOwnPlayerPassEndXPassEndYDeletedEventTypeFormationSlotBlockedXCoordinateBlockedYCoordinateisHeadisDirectisIntentionalAssistisChippedisLayOffisLaunchisOutOfPlayisFlickOnisBoxCentreisParriedSafeisCollectedisStandingisDivingisOutOfBoxCentreisStoopingisHandsisBlockedCrossisPlayerNotVisibleCaptainisSwitchOfPlayTeamKitisGkKickFromHandsisCrossisRightFootedisGameEndisOtherBodyPartisOverrunLengthAngleisBigChanceisIndividualPlayisRegularPlayisInswingerisOutswingerisStraightResumeisOwnShotBlockedisPostMatchCompleteGkXCoordinateGkYCoordinateOppositeRelatedEventIdisBlockedPassisLowisSetPieceisGkStartisIndirectisFromCornerisOpenRoofAirHumidityAirPressureCelSiusDegreesisAttemptedTackleKickOffisDefensiveisOffensiveisOverArmisAssistedDetailedPositionIdisPositionSideIdisShovePushisShirtPullHoldingisHeadPassInvolvedisChecksCompleteisYellowCardisFirstTouchisThroughBallInjuryisTacticalPlayerPositionConditionsFieldPitchAttendanceFigureisFreeKickTakenInjuredPlayerIdRelatedEventIdZoneisEndTypeJerseyNumberisCornerTakenisBoxRightisBoxLeftPlayersCaughtOffsideisLeftFootedisLeftisHighisRightisLowLeftisLowCentreisLowRightisBlockedisHighClaimisDefBlockevent_nameindexFirstNameLastNameFullNameFormation_PlacePositionJerseyNoStatusteam_HATimeOnTimeOffMins.PlayedMatchIDisAerialFoulisHandisOwnGoalisPenaltyisSecondYellowisRedCardisPassisPassSuccessfulisPassUnsuccessfulisCrossOPisCrossOPSuccessfulisCrossOPUnsuccessfulisOffensivePassisOffensivePassWonisOffensivePassLostisBackwardPassisSidewayPassisLongPassisLongPassWonisLongPassLostisAerialisAerialWonisAerialLostisGroundDuelisGroundDuelWonisGroundDuelLostisFoulWonisFoulConcededisHandballConcededisCornerisCrossCornerisShortCornerisCornerIntoBoxSuccessfulisCornerIntoBoxUnsuccessfulisInterceptionsisTackleWonisTackleLostisSaveisSaveBlockOutfielderisClaimisClearanceLostisHeadedClearanceWonisHeadedClearanceLostisShotisShotOnTargetisShotOffTargetisShotOPisShotSetPieceisShotPenaltyisHeadedShotisHeadedShotOnTargetisHeadedShotOffTargetisGoalisGoalOPisGoalSetPieceisGoalPenaltyisShotBlockedByOutfielderisTouchisSuccessfulTakeOnisUnsuccessfulTakeOnisPenaltyConcededis2ndYellowCardxGxTMatchHome TeamAway Team
0523386962993110031150.250.02021-10-03T14:00:24.5762021-10-03T22:27:55163329647495650471.0000.0NaN0.00.00.00.00.0NaN0NaNNaN0.033.149.0NaNNaNNaNNaN0.00.00.00.00.00.00.00.00.00.00.01.00.00.00.00.00.00.0NaN0.0NaN0.00.00.00.00.0018.03.20.00.00.00.00.00.0NaN0.00.0NaNNaNNaN0.00.00.00.00.00.00.0NaNNaNNaN0.0S0.00.00.00.0NaN0.00.00.00.0NaN0.000.00.0NaN0.0NaNNaNNaNNaN0NaNNaNBack0.0NaN0.00.00.0NaN0.00.00.00.00.00.00.00.00.00.0isPass28.0JamesMcArthurJames McArthur8.0Midfielder18.0Start1.00.096.096.0f221033400000011000000010000000000000000000000000000000000000000010000NaN-0.00352203/10/2021: Crystal Palace (2) vs. (2) Leicest...Crystal PalaceLeicester City
1623386963194110231132.949.02021-10-03T14:00:26.9982021-10-03T22:28:021633296482303174874.0000.0NaN0.00.00.00.00.0NaN0NaNNaN0.035.369.4NaNNaNNaNNaN0.00.00.00.00.00.00.00.00.00.00.01.00.00.00.00.00.00.0NaN0.0NaN0.00.00.00.00.0014.11.40.00.00.00.00.00.0NaN0.00.0NaNNaNNaN0.00.00.00.00.00.00.0NaNNaNNaN0.0NaN0.00.00.00.0NaN0.00.00.00.0NaN0.000.00.0NaN0.0NaNNaNNaNNaN0NaNNaNBack0.0NaN0.00.00.0NaN0.00.00.00.00.00.00.00.00.00.0isPass11.0JoachimAndersenJoachim Andersen5.0Defender16.0Start1.00.096.096.0f221033400000011000011000000000000000000000000000000000000000000010000NaN-0.00072903/10/2021: Crystal Palace (2) vs. (2) Leicest...Crystal PalaceLeicester City
2723386964295110431136.471.02021-10-03T14:00:29.1672021-10-03T22:28:051633296485941209036.0000.0NaN0.00.00.00.00.0NaN0NaNNaN0.042.489.0NaNNaNNaNNaN0.00.00.00.00.00.00.00.00.00.00.01.00.00.00.00.00.00.0NaN0.0NaN0.00.00.00.00.0013.81.10.00.00.00.00.00.0NaN0.00.0NaNNaNNaN0.00.00.00.00.00.00.0NaNNaNNaN0.0NaN0.00.00.00.0NaN0.00.00.00.0NaN0.000.00.0NaN0.0NaNNaNNaNNaN0NaNNaNBack0.0NaN0.00.00.0NaN0.00.00.00.00.00.00.00.00.00.0isPass16.0MarcGuéhiMarc Guéhi6.0Defender6.0Start1.00.096.096.0f221033400000011000011000000000000000000000000000000000000000000010000NaNNaN03/10/2021: Crystal Palace (2) vs. (2) Leicest...Crystal PalaceLeicester City
\n", "
" ], "text/plain": [ " Unnamed: 0 id event_id type_id period_id min sec team_id \\\n", "0 5 2338696299 3 1 1 0 0 31 \n", "1 6 2338696319 4 1 1 0 2 31 \n", "2 7 2338696429 5 1 1 0 4 31 \n", "\n", " outcome x y timestamp last_modified \\\n", "0 1 50.2 50.0 2021-10-03T14:00:24.576 2021-10-03T22:27:55 \n", "1 1 32.9 49.0 2021-10-03T14:00:26.998 2021-10-03T22:28:02 \n", "2 1 36.4 71.0 2021-10-03T14:00:29.167 2021-10-03T22:28:05 \n", "\n", " version player_id isKeyPass isAssist isLongBall \\\n", "0 1633296474956 50471.0 0 0 0.0 \n", "1 1633296482303 174874.0 0 0 0.0 \n", "2 1633296485941 209036.0 0 0 0.0 \n", "\n", " GoalMouthYCoordinate isGoalMouthZCoordinate isThrowIn isVolley \\\n", "0 NaN 0.0 0.0 0.0 \n", "1 NaN 0.0 0.0 0.0 \n", "2 NaN 0.0 0.0 0.0 \n", "\n", " isKeeperThrow isGoalKick DirectionOfPlay isFoul TeamFormation \\\n", "0 0.0 0.0 NaN 0 NaN \n", "1 0.0 0.0 NaN 0 NaN \n", "2 0.0 0.0 NaN 0 NaN \n", "\n", " TeamPlayerFormation isOwnPlayer PassEndX PassEndY DeletedEventType \\\n", "0 NaN 0.0 33.1 49.0 NaN \n", "1 NaN 0.0 35.3 69.4 NaN \n", "2 NaN 0.0 42.4 89.0 NaN \n", "\n", " FormationSlot BlockedXCoordinate BlockedYCoordinate isHead isDirect \\\n", "0 NaN NaN NaN 0.0 0.0 \n", "1 NaN NaN NaN 0.0 0.0 \n", "2 NaN NaN NaN 0.0 0.0 \n", "\n", " isIntentionalAssist isChipped isLayOff isLaunch isOutOfPlay isFlickOn \\\n", "0 0.0 0.0 0.0 0.0 0.0 0.0 \n", "1 0.0 0.0 0.0 0.0 0.0 0.0 \n", "2 0.0 0.0 0.0 0.0 0.0 0.0 \n", "\n", " isBoxCentre isParriedSafe isCollected isStanding isDiving \\\n", "0 0.0 0.0 0.0 1.0 0.0 \n", "1 0.0 0.0 0.0 1.0 0.0 \n", "2 0.0 0.0 0.0 1.0 0.0 \n", "\n", " isOutOfBoxCentre isStooping isHands isBlockedCross isPlayerNotVisible \\\n", "0 0.0 0.0 0.0 0.0 0.0 \n", "1 0.0 0.0 0.0 0.0 0.0 \n", "2 0.0 0.0 0.0 0.0 0.0 \n", "\n", " Captain isSwitchOfPlay TeamKit isGkKickFromHands isCross \\\n", "0 NaN 0.0 NaN 0.0 0.0 \n", "1 NaN 0.0 NaN 0.0 0.0 \n", "2 NaN 0.0 NaN 0.0 0.0 \n", "\n", " isRightFooted isGameEnd isOtherBodyPart isOverrun Length Angle \\\n", "0 0.0 0.0 0.0 0 18.0 3.2 \n", "1 0.0 0.0 0.0 0 14.1 1.4 \n", "2 0.0 0.0 0.0 0 13.8 1.1 \n", "\n", " isBigChance isIndividualPlay isRegularPlay isInswinger isOutswinger \\\n", "0 0.0 0.0 0.0 0.0 0.0 \n", "1 0.0 0.0 0.0 0.0 0.0 \n", "2 0.0 0.0 0.0 0.0 0.0 \n", "\n", " isStraight Resume isOwnShotBlocked isPostMatchComplete GkXCoordinate \\\n", "0 0.0 NaN 0.0 0.0 NaN \n", "1 0.0 NaN 0.0 0.0 NaN \n", "2 0.0 NaN 0.0 0.0 NaN \n", "\n", " GkYCoordinate OppositeRelatedEventId isBlockedPass isLow isSetPiece \\\n", "0 NaN NaN 0.0 0.0 0.0 \n", "1 NaN NaN 0.0 0.0 0.0 \n", "2 NaN NaN 0.0 0.0 0.0 \n", "\n", " isGkStart isIndirect isFromCorner isOpenRoof AirHumidity AirPressure \\\n", "0 0.0 0.0 0.0 0.0 NaN NaN \n", "1 0.0 0.0 0.0 0.0 NaN NaN \n", "2 0.0 0.0 0.0 0.0 NaN NaN \n", "\n", " CelSiusDegrees isAttemptedTackle KickOff isDefensive isOffensive \\\n", "0 NaN 0.0 S 0.0 0.0 \n", "1 NaN 0.0 NaN 0.0 0.0 \n", "2 NaN 0.0 NaN 0.0 0.0 \n", "\n", " isOverArm isAssisted DetailedPositionId isPositionSideId isShovePush \\\n", "0 0.0 0.0 NaN 0.0 0.0 \n", "1 0.0 0.0 NaN 0.0 0.0 \n", "2 0.0 0.0 NaN 0.0 0.0 \n", "\n", " isShirtPullHolding isHeadPass Involved isChecksComplete isYellowCard \\\n", "0 0.0 0.0 NaN 0.0 0 \n", "1 0.0 0.0 NaN 0.0 0 \n", "2 0.0 0.0 NaN 0.0 0 \n", "\n", " isFirstTouch isThroughBall Injury isTactical PlayerPosition Conditions \\\n", "0 0.0 0.0 NaN 0.0 NaN NaN \n", "1 0.0 0.0 NaN 0.0 NaN NaN \n", "2 0.0 0.0 NaN 0.0 NaN NaN \n", "\n", " FieldPitch AttendanceFigure isFreeKickTaken InjuredPlayerId \\\n", "0 NaN NaN 0 NaN \n", "1 NaN NaN 0 NaN \n", "2 NaN NaN 0 NaN \n", "\n", " RelatedEventId Zone isEndType JerseyNumber isCornerTaken isBoxRight \\\n", "0 NaN Back 0.0 NaN 0.0 0.0 \n", "1 NaN Back 0.0 NaN 0.0 0.0 \n", "2 NaN Back 0.0 NaN 0.0 0.0 \n", "\n", " isBoxLeft PlayersCaughtOffside isLeftFooted isLeft isHigh isRight \\\n", "0 0.0 NaN 0.0 0.0 0.0 0.0 \n", "1 0.0 NaN 0.0 0.0 0.0 0.0 \n", "2 0.0 NaN 0.0 0.0 0.0 0.0 \n", "\n", " isLowLeft isLowCentre isLowRight isBlocked isHighClaim isDefBlock \\\n", "0 0.0 0.0 0.0 0.0 0.0 0.0 \n", "1 0.0 0.0 0.0 0.0 0.0 0.0 \n", "2 0.0 0.0 0.0 0.0 0.0 0.0 \n", "\n", " event_name index FirstName LastName FullName Formation_Place \\\n", "0 isPass 28.0 James McArthur James McArthur 8.0 \n", "1 isPass 11.0 Joachim Andersen Joachim Andersen 5.0 \n", "2 isPass 16.0 Marc Guéhi Marc Guéhi 6.0 \n", "\n", " Position JerseyNo Status team_HA TimeOn TimeOff Mins.Played \\\n", "0 Midfielder 18.0 Start 1.0 0.0 96.0 96.0 \n", "1 Defender 16.0 Start 1.0 0.0 96.0 96.0 \n", "2 Defender 6.0 Start 1.0 0.0 96.0 96.0 \n", "\n", " MatchID isAerialFoul isHand isOwnGoal isPenalty isSecondYellow \\\n", "0 f2210334 0 0 0 0 0 \n", "1 f2210334 0 0 0 0 0 \n", "2 f2210334 0 0 0 0 0 \n", "\n", " isRedCard isPass isPassSuccessful isPassUnsuccessful isCrossOP \\\n", "0 0 1 1 0 0 \n", "1 0 1 1 0 0 \n", "2 0 1 1 0 0 \n", "\n", " isCrossOPSuccessful isCrossOPUnsuccessful isOffensivePass \\\n", "0 0 0 0 \n", "1 0 0 1 \n", "2 0 0 1 \n", "\n", " isOffensivePassWon isOffensivePassLost isBackwardPass isSidewayPass \\\n", "0 0 0 1 0 \n", "1 1 0 0 0 \n", "2 1 0 0 0 \n", "\n", " isLongPass isLongPassWon isLongPassLost isAerial isAerialWon \\\n", "0 0 0 0 0 0 \n", "1 0 0 0 0 0 \n", "2 0 0 0 0 0 \n", "\n", " isAerialLost isGroundDuel isGroundDuelWon isGroundDuelLost isFoulWon \\\n", "0 0 0 0 0 0 \n", "1 0 0 0 0 0 \n", "2 0 0 0 0 0 \n", "\n", " isFoulConceded isHandballConceded isCorner isCrossCorner isShortCorner \\\n", "0 0 0 0 0 0 \n", "1 0 0 0 0 0 \n", "2 0 0 0 0 0 \n", "\n", " isCornerIntoBoxSuccessful isCornerIntoBoxUnsuccessful isInterceptions \\\n", "0 0 0 0 \n", "1 0 0 0 \n", "2 0 0 0 \n", "\n", " isTackleWon isTackleLost isSave isSaveBlockOutfielder isClaim \\\n", "0 0 0 0 0 0 \n", "1 0 0 0 0 0 \n", "2 0 0 0 0 0 \n", "\n", " isClearanceLost isHeadedClearanceWon isHeadedClearanceLost isShot \\\n", "0 0 0 0 0 \n", "1 0 0 0 0 \n", "2 0 0 0 0 \n", "\n", " isShotOnTarget isShotOffTarget isShotOP isShotSetPiece isShotPenalty \\\n", "0 0 0 0 0 0 \n", "1 0 0 0 0 0 \n", "2 0 0 0 0 0 \n", "\n", " isHeadedShot isHeadedShotOnTarget isHeadedShotOffTarget isGoal \\\n", "0 0 0 0 0 \n", "1 0 0 0 0 \n", "2 0 0 0 0 \n", "\n", " isGoalOP isGoalSetPiece isGoalPenalty isShotBlockedByOutfielder \\\n", "0 0 0 0 0 \n", "1 0 0 0 0 \n", "2 0 0 0 0 \n", "\n", " isTouch isSuccessfulTakeOn isUnsuccessfulTakeOn isPenaltyConceded \\\n", "0 1 0 0 0 \n", "1 1 0 0 0 \n", "2 1 0 0 0 \n", "\n", " is2ndYellowCard xG xT \\\n", "0 0 NaN -0.003522 \n", "1 0 NaN -0.000729 \n", "2 0 NaN NaN \n", "\n", " Match Home Team \\\n", "0 03/10/2021: Crystal Palace (2) vs. (2) Leicest... Crystal Palace \n", "1 03/10/2021: Crystal Palace (2) vs. (2) Leicest... Crystal Palace \n", "2 03/10/2021: Crystal Palace (2) vs. (2) Leicest... Crystal Palace \n", "\n", " Away Team \n", "0 Leicester City \n", "1 Leicester City \n", "2 Leicester City " ] }, "execution_count": 79, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_cry_lei_events.head(3)" ] }, { "cell_type": "code", "execution_count": 209, "metadata": {}, "outputs": [], "source": [ "# Define function to \n", "def create_passing_matrix(df_events):\n", " \n", " \"\"\"\n", " Function to...\n", " \"\"\"\n", " \n", " ##\n", " df_events = df_events.sort_values(['MatchID', 'event_id', 'period_id'], ascending=[True, True, True])\n", "\n", " \n", " df_events['PassRecipientLastName'] = df_events['LastName'].shift(-1)\n", " df_events['PassRecipientId'] = df_events['player_id'].shift(-1)\n", " \n", " ## Select columns of interest\n", " df_events = df_events[['event_id', 'MatchID','period_id', 'team_id', 'outcome', 'isPass', 'isTouch', 'xG', 'xT', 'player_id', 'FirstName', 'LastName', 'FullName', 'PassRecipientLastName', 'PassRecipientId', 'event_name', 'x', 'y', 'PassEndX', 'PassEndY']]\n", " \n", " ## \n", " df_events = df_events[(df_events['isPass'] == 1)]\n", " \n", " ## \n", " df1 = df_events.copy()\n", " \n", " ## \n", " df1 = df1[(df1['isTouch'] == 1)]\n", " \n", " ## \n", " df1['df_name'] = 'df1'\n", " \n", " ## \n", " df2 = df_events.copy()\n", " \n", " ## \n", " df2['df_name'] = 'df2'\n", " \n", " ## \n", " df_events = pd.concat([df1, df2])\n", " \n", " ## \n", " df_events['Pass_X'] = np.where(df_events['df_name'] == 'df1', df_events['x'], df_events['PassEndX'])\n", " df_events['Pass_Y'] = np.where(df_events['df_name'] == 'df1', df_events['y'], df_events['PassEndY'])\n", " #df_events['Carry_X'] = np.where(df_events['df_name'] == 'df1', df_events['x'], df_events['carry_end_x'])\n", " #df_events['Carry_Y'] = np.where(df_events['df_name'] == 'df1', df_events['y'], df_events['carry_end_y'])\n", "\n", " ## Return DataFrame\n", " return df_events" ] }, { "cell_type": "code", "execution_count": 210, "metadata": {}, "outputs": [], "source": [ "df_cry_lei_events_passing_matrix = create_passing_matrix(df_cry_lei_events)\n", "df_cry_bri_events_passing_matrix = create_passing_matrix(df_cry_bri_events)" ] }, { "cell_type": "code", "execution_count": 211, "metadata": {}, "outputs": [], "source": [ "df_cry_lei_events_passing_matrix['Match'] = '27/09/2021: Crystal Palace (1) vs. (1) Brighton & Hove Albion'\n", "df_cry_bri_events_passing_matrix['Match'] = '03/10/2021: Crystal Palace (2) vs. (2) Leicester City'" ] }, { "cell_type": "code", "execution_count": 212, "metadata": {}, "outputs": [], "source": [ "df_passing_matrix = pd.concat([df_cry_lei_events_passing_matrix, df_cry_bri_events_passing_matrix])\n", "df_passing_matrix = df_passing_matrix[df_passing_matrix['Pass_X'].notna()]\n", "df_passing_matrix = df_passing_matrix[df_passing_matrix['Pass_Y'].notna()]" ] }, { "cell_type": "code", "execution_count": 213, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
event_idMatchIDperiod_idteam_idoutcomeisPassisTouchxGxTplayer_idFirstNameLastNameFullNamePassRecipientLastNamePassRecipientIdevent_namexyPassEndXPassEndYdf_namePass_XPass_YMatch
03f2210334131111NaN-0.00352250471.0JamesMcArthurJames McArthurAndersen174874.0isPass50.250.033.149.0df150.250.027/09/2021: Crystal Palace (1) vs. (1) Brighto...
14f2210334131111NaN-0.000729174874.0JoachimAndersenJoachim AndersenChoudhury197469.0isPass32.949.035.369.4df132.949.027/09/2021: Crystal Palace (1) vs. (1) Brighto...
44f2210334113011NaN0.008530197469.0HamzaChoudhuryHamza ChoudhuryGuéhi209036.0isPass46.027.884.30.0df146.027.827/09/2021: Crystal Palace (1) vs. (1) Brighto...
25f2210334131111NaNNaN209036.0MarcGuéhiMarc GuéhiMitchell244723.0isPass36.471.042.489.0df136.471.027/09/2021: Crystal Palace (1) vs. (1) Brighto...
36f2210334131011NaN0.001221244723.0TyrickMitchellTyrick MitchellIheanacho173515.0isPass45.876.653.975.4df145.876.627/09/2021: Crystal Palace (1) vs. (1) Brighto...
\n", "
" ], "text/plain": [ " event_id MatchID period_id team_id outcome isPass isTouch xG \\\n", "0 3 f2210334 1 31 1 1 1 NaN \n", "1 4 f2210334 1 31 1 1 1 NaN \n", "4 4 f2210334 1 13 0 1 1 NaN \n", "2 5 f2210334 1 31 1 1 1 NaN \n", "3 6 f2210334 1 31 0 1 1 NaN \n", "\n", " xT player_id FirstName LastName FullName \\\n", "0 -0.003522 50471.0 James McArthur James McArthur \n", "1 -0.000729 174874.0 Joachim Andersen Joachim Andersen \n", "4 0.008530 197469.0 Hamza Choudhury Hamza Choudhury \n", "2 NaN 209036.0 Marc Guéhi Marc Guéhi \n", "3 0.001221 244723.0 Tyrick Mitchell Tyrick Mitchell \n", "\n", " PassRecipientLastName PassRecipientId event_name x y PassEndX \\\n", "0 Andersen 174874.0 isPass 50.2 50.0 33.1 \n", "1 Choudhury 197469.0 isPass 32.9 49.0 35.3 \n", "4 Guéhi 209036.0 isPass 46.0 27.8 84.3 \n", "2 Mitchell 244723.0 isPass 36.4 71.0 42.4 \n", "3 Iheanacho 173515.0 isPass 45.8 76.6 53.9 \n", "\n", " PassEndY df_name Pass_X Pass_Y \\\n", "0 49.0 df1 50.2 50.0 \n", "1 69.4 df1 32.9 49.0 \n", "4 0.0 df1 46.0 27.8 \n", "2 89.0 df1 36.4 71.0 \n", "3 75.4 df1 45.8 76.6 \n", "\n", " Match \n", "0 27/09/2021: Crystal Palace (1) vs. (1) Brighto... \n", "1 27/09/2021: Crystal Palace (1) vs. (1) Brighto... \n", "4 27/09/2021: Crystal Palace (1) vs. (1) Brighto... \n", "2 27/09/2021: Crystal Palace (1) vs. (1) Brighto... \n", "3 27/09/2021: Crystal Palace (1) vs. (1) Brighto... " ] }, "execution_count": 213, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_passing_matrix.head(5)" ] }, { "cell_type": "code", "execution_count": 214, "metadata": {}, "outputs": [], "source": [ "df_passing_matrix.to_csv(os.path.join(data_dir_opta, 'engineered', 'F24', 'f24-passing-matrix-merged.csv'), index=None, header=True)" ] }, { "cell_type": "code", "execution_count": 215, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(4002, 24)" ] }, "execution_count": 215, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_passing_matrix.shape" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "\n", "### 4.18. Create Passing Network DataFrame\n", "See: https://community.tableau.com/s/question/0D54T00000C6YbE/football-passing-network" ] }, { "cell_type": "code", "execution_count": 327, "metadata": {}, "outputs": [], "source": [ "df_cry_bri_events['Match'] = '27/09/2021: Crystal Palace (1) vs. (1) Brighton & Hove Albion'\n", "df_cry_lei_events['Match'] = '03/10/2021: Crystal Palace (2) vs. (2) Leicester City'" ] }, { "cell_type": "code", "execution_count": 328, "metadata": {}, "outputs": [], "source": [ "df_passing_network_bri_events = df_cry_bri_events" ] }, { "cell_type": "code", "execution_count": 329, "metadata": {}, "outputs": [], "source": [ "team_id = 36" ] }, { "cell_type": "code", "execution_count": 330, "metadata": {}, "outputs": [], "source": [ "# Data Engineering\n", "\n", "### Filter DataFrame for a single match and then only select team of interest\n", "df_passing_network_bri_events = df_passing_network_bri_events[(df_passing_network_bri_events['team_id'] == team_id)].reset_index(drop=True)\n", "\n", "### Determine Pass recipient ID\n", "df_passing_network_bri_events['pass_recipient_id'] = df_passing_network_bri_events['player_id'].shift(-1)\n", "\n", "### Determine passers and recipients by ID and then filter for only passes\n", "df_passing_network_bri_events['passer'] = df_passing_network_bri_events['player_id']\n", "df_passing_network_bri_events['recipient'] = df_passing_network_bri_events['pass_recipient_id']\n", "\n", "### Filter DataFrame for only passes and then only look for the successful passes\n", "df_passing_network_bri_events_passes = df_passing_network_bri_events[df_passing_network_bri_events['isPass']==1]\n", "df_passing_network_bri_events_successful = df_passing_network_bri_events_passes[df_passing_network_bri_events_passes['outcome'] == 1]\n", "\n", "\n", "### Filter time\n", "#period_mask = (df_passing_network_bri_events_successful['period'] >= period_start) & (df_passing_network_bri_events_successful['period'] <= period_end)\n", "#minute_mask = (df_passing_network_bri_events_successful['minute'] >= minute_start) & (df_passing_network_bri_events_successful['minute'] <= minute_end)\n", "#df_passing_network_bri_events_successful = df_passing_network_bri_events_successful.loc[(period_mask & minute_mask)]\n", "#df_passing_network_bri_events_successful = df_passing_network_bri_events_successful.loc[minute_mask]\n", "\n", "\n", "### Determine the first subsititution and filter the successful dataframe to be less than that minute\n", "df_passing_network_bri_events_subs = df_passing_network_bri_events[df_passing_network_bri_events['event_id']==23]\n", "df_passing_network_bri_events_subs = df_passing_network_bri_events_subs['min']\n", "\n", "\n", "#### Determine when the first substitute took place\n", "#first_sub = df_passing_network_bri_events_subs.min()\n", "\n", "\n", "#### Filter DataFrame of successful pass for up until the first substitute takes place in the match\n", "#df_passing_network_bri_events_successful = df_passing_network_bri_events_successful[df_passing_network_bri_events_successful['minute'] < first_sub]\n", "\n", "\n", "### Convert IDs of passer and recipients are floats\n", "pas = pd.to_numeric(df_passing_network_bri_events_successful['passer'], downcast='integer')\n", "rec = pd.to_numeric(df_passing_network_bri_events_successful['recipient'], downcast='integer')\n", "df_passing_network_bri_events_successful['passer'] = pas\n", "df_passing_network_bri_events_successful['recipient'] = rec\n", "df_passing_network_bri_events_successful['passer'] = df_passing_network_bri_events_successful['passer'].astype(float)\n", "df_passing_network_bri_events_successful['recipient'] = df_passing_network_bri_events_successful['recipient'].astype(float)\n", "\n", "### Determine the average locations and counts of the passes\n", "df_passing_network_bri_events_average_locations = (df_passing_network_bri_events_successful\n", " .groupby(['FullName', 'passer'])\n", " .agg({'x':['mean'],\n", " 'y':['mean','count']\n", " }\n", " )\n", " )\n", "\n", "\n", "### Rename columns after groupby and aggregation\n", "df_passing_network_bri_events_average_locations.columns = ['x', 'y', 'count']\n", "\n", "\n", "#### Reset index\n", "df_passing_network_bri_events_average_locations = df_passing_network_bri_events_average_locations.reset_index(drop=False)\n", "\n", "\n", "### Groupby and aggregate the the number of passes between passers and recipients\n", "\n", "#### Now we need to find the number of passes between each player\n", "df_passing_network_bri_events_pass_between = (df_passing_network_bri_events_successful\n", " .groupby(['Match', 'FullName', 'team_id', 'passer', 'recipient', 'JerseyNo'])\n", " .id.count()\n", " .reset_index()\n", " )\n", "\n", "#### Rename columns\n", "df_passing_network_bri_events_pass_between = df_passing_network_bri_events_pass_between.rename({'FullName':'passer_name',\n", " 'id':'pass_count'\n", " }, axis='columns')\n", "\n", "\n", "\n", "### Merge the average location dataframe. We need to merge on the passer first then the recipient\n", "\n", "####\n", "df_passing_network_bri_events_pass_between = df_passing_network_bri_events_pass_between.merge(df_passing_network_bri_events_average_locations, left_on='passer', right_on='passer')\n", "df_passing_network_bri_events_pass_between = df_passing_network_bri_events_pass_between.merge(df_passing_network_bri_events_average_locations, left_on='recipient', right_on='passer', suffixes=['', '_end'])\n", "\n", "#### Set minimum threshold of combinations\n", "#df_passing_network_bri_events_pass_between = df_passing_network_bri_events_pass_between[df_passing_network_bri_events_pass_between['pass_count'] >= pass_threshold]\n", "\n", "### Select columns of interest\n", "df_passing_network_bri_events_unique_nodes = df_passing_network_bri_events_pass_between[['passer_name', 'passer', 'x', 'y']].drop_duplicates()\n", "df_passing_network_bri_events_unique_nodes['pass_surname'] = df_passing_network_bri_events_unique_nodes['passer_name'].str.split(' ').str[-1]" ] }, { "cell_type": "code", "execution_count": 331, "metadata": {}, "outputs": [], "source": [ "df_passing_network_bri_events_pass_between['PassToFrom'] = df_passing_network_bri_events_pass_between['FullName'] + ' - ' + df_passing_network_bri_events_pass_between['FullName_end']" ] }, { "cell_type": "code", "execution_count": 332, "metadata": {}, "outputs": [], "source": [ "df_passing_network_bri_events_pass_between.to_csv('test.csv')" ] }, { "cell_type": "code", "execution_count": 333, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
Matchpasser_nameteam_idpasserrecipientJerseyNopass_countFullNamexycountFullName_endpasser_endx_endy_endcount_endPassToFrom
027/09/2021: Crystal Palace (1) vs. (1) Brighto...Aaron Connolly36233425.0179268.07.01Aaron Connolly79.30000077.9000001Marc Cucurella179268.051.86730892.73846252Aaron Connolly - Marc Cucurella
127/09/2021: Crystal Palace (1) vs. (1) Brighto...Adam Lallana3639155.0179268.014.06Adam Lallana46.27234053.25957447Marc Cucurella179268.051.86730892.73846252Adam Lallana - Marc Cucurella
227/09/2021: Crystal Palace (1) vs. (1) Brighto...Dan Burn3678916.0179268.033.04Dan Burn32.93333379.99583324Marc Cucurella179268.051.86730892.73846252Dan Burn - Marc Cucurella
327/09/2021: Crystal Palace (1) vs. (1) Brighto...Danny Welbeck3650175.0179268.018.08Danny Welbeck68.01538585.25384613Marc Cucurella179268.051.86730892.73846252Danny Welbeck - Marc Cucurella
427/09/2021: Crystal Palace (1) vs. (1) Brighto...Leandro Trossard36116216.0179268.011.06Leandro Trossard57.36774245.29354831Marc Cucurella179268.051.86730892.73846252Leandro Trossard - Marc Cucurella
......................................................
10327/09/2021: Crystal Palace (1) vs. (1) Brighto...Pascal Groß3660307.0215059.013.01Pascal Groß49.47234050.16170247Robert Sánchez215059.012.60000052.10666745Pascal Groß - Robert Sánchez
10427/09/2021: Crystal Palace (1) vs. (1) Brighto...Robert Sánchez36215059.0215059.01.01Robert Sánchez12.60000052.10666745Robert Sánchez215059.012.60000052.10666745Robert Sánchez - Robert Sánchez
10527/09/2021: Crystal Palace (1) vs. (1) Brighto...Shane Duffy3661933.0215059.024.015Shane Duffy27.24117631.42549051Robert Sánchez215059.012.60000052.10666745Shane Duffy - Robert Sánchez
10627/09/2021: Crystal Palace (1) vs. (1) Brighto...Steven Alzate36235382.0215059.017.02Steven Alzate43.54166780.04166712Robert Sánchez215059.012.60000052.10666745Steven Alzate - Robert Sánchez
10727/09/2021: Crystal Palace (1) vs. (1) Brighto...Pascal Groß3660307.0233425.013.02Pascal Groß49.47234050.16170247Aaron Connolly233425.079.30000077.9000001Pascal Groß - Aaron Connolly
\n", "

108 rows × 17 columns

\n", "
" ], "text/plain": [ " Match passer_name \\\n", "0 27/09/2021: Crystal Palace (1) vs. (1) Brighto... Aaron Connolly \n", "1 27/09/2021: Crystal Palace (1) vs. (1) Brighto... Adam Lallana \n", "2 27/09/2021: Crystal Palace (1) vs. (1) Brighto... Dan Burn \n", "3 27/09/2021: Crystal Palace (1) vs. (1) Brighto... Danny Welbeck \n", "4 27/09/2021: Crystal Palace (1) vs. (1) Brighto... Leandro Trossard \n", ".. ... ... \n", "103 27/09/2021: Crystal Palace (1) vs. (1) Brighto... Pascal Groß \n", "104 27/09/2021: Crystal Palace (1) vs. (1) Brighto... Robert Sánchez \n", "105 27/09/2021: Crystal Palace (1) vs. (1) Brighto... Shane Duffy \n", "106 27/09/2021: Crystal Palace (1) vs. (1) Brighto... Steven Alzate \n", "107 27/09/2021: Crystal Palace (1) vs. (1) Brighto... Pascal Groß \n", "\n", " team_id passer recipient JerseyNo pass_count FullName \\\n", "0 36 233425.0 179268.0 7.0 1 Aaron Connolly \n", "1 36 39155.0 179268.0 14.0 6 Adam Lallana \n", "2 36 78916.0 179268.0 33.0 4 Dan Burn \n", "3 36 50175.0 179268.0 18.0 8 Danny Welbeck \n", "4 36 116216.0 179268.0 11.0 6 Leandro Trossard \n", ".. ... ... ... ... ... ... \n", "103 36 60307.0 215059.0 13.0 1 Pascal Groß \n", "104 36 215059.0 215059.0 1.0 1 Robert Sánchez \n", "105 36 61933.0 215059.0 24.0 15 Shane Duffy \n", "106 36 235382.0 215059.0 17.0 2 Steven Alzate \n", "107 36 60307.0 233425.0 13.0 2 Pascal Groß \n", "\n", " x y count FullName_end passer_end x_end \\\n", "0 79.300000 77.900000 1 Marc Cucurella 179268.0 51.867308 \n", "1 46.272340 53.259574 47 Marc Cucurella 179268.0 51.867308 \n", "2 32.933333 79.995833 24 Marc Cucurella 179268.0 51.867308 \n", "3 68.015385 85.253846 13 Marc Cucurella 179268.0 51.867308 \n", "4 57.367742 45.293548 31 Marc Cucurella 179268.0 51.867308 \n", ".. ... ... ... ... ... ... \n", "103 49.472340 50.161702 47 Robert Sánchez 215059.0 12.600000 \n", "104 12.600000 52.106667 45 Robert Sánchez 215059.0 12.600000 \n", "105 27.241176 31.425490 51 Robert Sánchez 215059.0 12.600000 \n", "106 43.541667 80.041667 12 Robert Sánchez 215059.0 12.600000 \n", "107 49.472340 50.161702 47 Aaron Connolly 233425.0 79.300000 \n", "\n", " y_end count_end PassToFrom \n", "0 92.738462 52 Aaron Connolly - Marc Cucurella \n", "1 92.738462 52 Adam Lallana - Marc Cucurella \n", "2 92.738462 52 Dan Burn - Marc Cucurella \n", "3 92.738462 52 Danny Welbeck - Marc Cucurella \n", "4 92.738462 52 Leandro Trossard - Marc Cucurella \n", ".. ... ... ... \n", "103 52.106667 45 Pascal Groß - Robert Sánchez \n", "104 52.106667 45 Robert Sánchez - Robert Sánchez \n", "105 52.106667 45 Shane Duffy - Robert Sánchez \n", "106 52.106667 45 Steven Alzate - Robert Sánchez \n", "107 77.900000 1 Pascal Groß - Aaron Connolly \n", "\n", "[108 rows x 17 columns]" ] }, "execution_count": 333, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_passing_network_bri_events_pass_between" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## OLD METHOD - NOT WORKING" ] }, { "cell_type": "code", "execution_count": 216, "metadata": {}, "outputs": [], "source": [ "df_passing_network = df_passing_matrix.copy()" ] }, { "cell_type": "code", "execution_count": 223, "metadata": {}, "outputs": [], "source": [ "##\n", "df_passing_network = df_passing_network.sort_values(['df_name', 'MatchID', 'event_id', 'period_id'], ascending=[True, True, True, True])" ] }, { "cell_type": "code", "execution_count": 224, "metadata": {}, "outputs": [], "source": [ "df_passing_network = df_passing_network[(df_passing_network['isPass'] == 1)]" ] }, { "cell_type": "code", "execution_count": 225, "metadata": {}, "outputs": [], "source": [ "df_passing_network['player_recipient'] = np.where(df_passing_network['df_name'] == 'df1', df_passing_network['LastName'], df_passing_network['PassRecipientLastName'])\n", "df_passing_network['player_recipient_id'] = np.where(df_passing_network['df_name'] == 'df1', df_passing_network['player_id'], df_passing_network['PassRecipientId'])" ] }, { "cell_type": "code", "execution_count": 226, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(4002, 27)" ] }, "execution_count": 226, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_passing_network.shape" ] }, { "cell_type": "code", "execution_count": 227, "metadata": {}, "outputs": [], "source": [ "df_passing_network['PassToFrom'] = df_passing_network['LastName'] + ' - ' + df_passing_network['PassRecipientLastName']" ] }, { "cell_type": "code", "execution_count": 228, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
event_idMatchIDperiod_idteam_idoutcomeisPassisTouchxGxTplayer_idFirstNameLastNameFullNamePassRecipientLastNamePassRecipientIdevent_namexyPassEndXPassEndYdf_namePass_XPass_YMatchplayer_recipientplayer_recipient_idPassToFrom
03f2210324136111NaN-0.001522115382.0NealMaupayNeal MaupayDunk83299.0isPass50.050.030.557.6df150.050.003/10/2021: Crystal Palace (2) vs. (2) Leicest...Maupay115382.0Maupay - Dunk
14f2210324136111NaNNaN83299.0LewisDunkLewis DunkAyew80146.0isPass32.561.764.696.2df132.561.703/10/2021: Crystal Palace (2) vs. (2) Leicest...Dunk83299.0Dunk - Ayew
35f2210324131111NaN0.00000080146.0JordanAyewJordan AyewBurn78916.0isPass36.58.632.89.8df136.58.603/10/2021: Crystal Palace (2) vs. (2) Leicest...Ayew80146.0Ayew - Burn
26f2210324136011NaNNaN78916.0DanBurnDan BurnWard55494.0isPass64.796.667.595.6df164.796.603/10/2021: Crystal Palace (2) vs. (2) Leicest...Burn78916.0Burn - Ward
47f2210324131111NaN-0.00180955494.0JoelWardJoel WardCucurella179268.0isPass32.410.619.914.8df132.410.603/10/2021: Crystal Palace (2) vs. (2) Leicest...Ward55494.0Ward - Cucurella
\n", "
" ], "text/plain": [ " event_id MatchID period_id team_id outcome isPass isTouch xG \\\n", "0 3 f2210324 1 36 1 1 1 NaN \n", "1 4 f2210324 1 36 1 1 1 NaN \n", "3 5 f2210324 1 31 1 1 1 NaN \n", "2 6 f2210324 1 36 0 1 1 NaN \n", "4 7 f2210324 1 31 1 1 1 NaN \n", "\n", " xT player_id FirstName LastName FullName PassRecipientLastName \\\n", "0 -0.001522 115382.0 Neal Maupay Neal Maupay Dunk \n", "1 NaN 83299.0 Lewis Dunk Lewis Dunk Ayew \n", "3 0.000000 80146.0 Jordan Ayew Jordan Ayew Burn \n", "2 NaN 78916.0 Dan Burn Dan Burn Ward \n", "4 -0.001809 55494.0 Joel Ward Joel Ward Cucurella \n", "\n", " PassRecipientId event_name x y PassEndX PassEndY df_name Pass_X \\\n", "0 83299.0 isPass 50.0 50.0 30.5 57.6 df1 50.0 \n", "1 80146.0 isPass 32.5 61.7 64.6 96.2 df1 32.5 \n", "3 78916.0 isPass 36.5 8.6 32.8 9.8 df1 36.5 \n", "2 55494.0 isPass 64.7 96.6 67.5 95.6 df1 64.7 \n", "4 179268.0 isPass 32.4 10.6 19.9 14.8 df1 32.4 \n", "\n", " Pass_Y Match player_recipient \\\n", "0 50.0 03/10/2021: Crystal Palace (2) vs. (2) Leicest... Maupay \n", "1 61.7 03/10/2021: Crystal Palace (2) vs. (2) Leicest... Dunk \n", "3 8.6 03/10/2021: Crystal Palace (2) vs. (2) Leicest... Ayew \n", "2 96.6 03/10/2021: Crystal Palace (2) vs. (2) Leicest... Burn \n", "4 10.6 03/10/2021: Crystal Palace (2) vs. (2) Leicest... Ward \n", "\n", " player_recipient_id PassToFrom \n", "0 115382.0 Maupay - Dunk \n", "1 83299.0 Dunk - Ayew \n", "3 80146.0 Ayew - Burn \n", "2 78916.0 Burn - Ward \n", "4 55494.0 Ward - Cucurella " ] }, "execution_count": 228, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_passing_network.head(5)" ] }, { "cell_type": "code", "execution_count": 229, "metadata": {}, "outputs": [], "source": [ "df_passing_network = df_passing_network[(df_passing_network['outcome'] == 1)]" ] }, { "cell_type": "code", "execution_count": 230, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(3174, 27)" ] }, "execution_count": 230, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_passing_network.shape" ] }, { "cell_type": "code", "execution_count": 187, "metadata": {}, "outputs": [], "source": [ "df_passing_network.to_csv('test.csv')" ] }, { "cell_type": "code", "execution_count": 236, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
MatchMatchIDteam_idplayer_idPassToFromLastNamePassRecipientLastNamePassRecipientIdplayer_recipientplayer_recipient_idCountPasses
32803/10/2021: Crystal Palace (2) vs. (2) Leicest...f22103243639155.0Lallana - AndersenLallanaAndersen174874.0Andersen174874.04
32903/10/2021: Crystal Palace (2) vs. (2) Leicest...f22103243639155.0Lallana - AndersenLallanaAndersen174874.0Lallana39155.04
33003/10/2021: Crystal Palace (2) vs. (2) Leicest...f22103243639155.0Lallana - AyewLallanaAyew80146.0Ayew80146.02
33103/10/2021: Crystal Palace (2) vs. (2) Leicest...f22103243639155.0Lallana - AyewLallanaAyew80146.0Lallana39155.02
33203/10/2021: Crystal Palace (2) vs. (2) Leicest...f22103243639155.0Lallana - CucurellaLallanaCucurella179268.0Cucurella179268.01
33303/10/2021: Crystal Palace (2) vs. (2) Leicest...f22103243639155.0Lallana - CucurellaLallanaCucurella179268.0Lallana39155.01
33403/10/2021: Crystal Palace (2) vs. (2) Leicest...f22103243639155.0Lallana - DuffyLallanaDuffy61933.0Duffy61933.01
33503/10/2021: Crystal Palace (2) vs. (2) Leicest...f22103243639155.0Lallana - DuffyLallanaDuffy61933.0Lallana39155.01
33603/10/2021: Crystal Palace (2) vs. (2) Leicest...f22103243639155.0Lallana - GallagherLallanaGallagher232787.0Gallagher232787.03
33703/10/2021: Crystal Palace (2) vs. (2) Leicest...f22103243639155.0Lallana - GallagherLallanaGallagher232787.0Lallana39155.03
\n", "
" ], "text/plain": [ " Match MatchID team_id \\\n", "328 03/10/2021: Crystal Palace (2) vs. (2) Leicest... f2210324 36 \n", "329 03/10/2021: Crystal Palace (2) vs. (2) Leicest... f2210324 36 \n", "330 03/10/2021: Crystal Palace (2) vs. (2) Leicest... f2210324 36 \n", "331 03/10/2021: Crystal Palace (2) vs. (2) Leicest... f2210324 36 \n", "332 03/10/2021: Crystal Palace (2) vs. (2) Leicest... f2210324 36 \n", "333 03/10/2021: Crystal Palace (2) vs. (2) Leicest... f2210324 36 \n", "334 03/10/2021: Crystal Palace (2) vs. (2) Leicest... f2210324 36 \n", "335 03/10/2021: Crystal Palace (2) vs. (2) Leicest... f2210324 36 \n", "336 03/10/2021: Crystal Palace (2) vs. (2) Leicest... f2210324 36 \n", "337 03/10/2021: Crystal Palace (2) vs. (2) Leicest... f2210324 36 \n", "\n", " player_id PassToFrom LastName PassRecipientLastName \\\n", "328 39155.0 Lallana - Andersen Lallana Andersen \n", "329 39155.0 Lallana - Andersen Lallana Andersen \n", "330 39155.0 Lallana - Ayew Lallana Ayew \n", "331 39155.0 Lallana - Ayew Lallana Ayew \n", "332 39155.0 Lallana - Cucurella Lallana Cucurella \n", "333 39155.0 Lallana - Cucurella Lallana Cucurella \n", "334 39155.0 Lallana - Duffy Lallana Duffy \n", "335 39155.0 Lallana - Duffy Lallana Duffy \n", "336 39155.0 Lallana - Gallagher Lallana Gallagher \n", "337 39155.0 Lallana - Gallagher Lallana Gallagher \n", "\n", " PassRecipientId player_recipient player_recipient_id CountPasses \n", "328 174874.0 Andersen 174874.0 4 \n", "329 174874.0 Lallana 39155.0 4 \n", "330 80146.0 Ayew 80146.0 2 \n", "331 80146.0 Lallana 39155.0 2 \n", "332 179268.0 Cucurella 179268.0 1 \n", "333 179268.0 Lallana 39155.0 1 \n", "334 61933.0 Duffy 61933.0 1 \n", "335 61933.0 Lallana 39155.0 1 \n", "336 232787.0 Gallagher 232787.0 3 \n", "337 232787.0 Lallana 39155.0 3 " ] }, "execution_count": 236, "metadata": {}, "output_type": "execute_result" } ], "source": [ "#\n", "\n", "##\n", "df_passing_network_grouped = (df_passing_network\n", " .groupby(['Match',\n", " 'MatchID',\n", " 'team_id',\n", " 'player_id',\n", " 'PassToFrom',\n", " 'LastName',\n", " 'PassRecipientLastName',\n", " 'PassRecipientId',\n", " 'player_recipient',\n", " 'player_recipient_id'\n", " ])\n", " .agg({'PassToFrom': ['count']\n", " })\n", " )\n", "\n", "##\n", "df_passing_network_grouped.columns = df_passing_network_grouped.columns.droplevel(level=0)\n", "\n", "##\n", "df_passing_network_grouped = df_passing_network_grouped.reset_index()\n", "\n", "## \n", "df_passing_network_grouped.columns = ['Match',\n", " 'MatchID',\n", " 'team_id',\n", " 'player_id',\n", " 'PassToFrom',\n", " 'LastName',\n", " 'PassRecipientLastName',\n", " 'PassRecipientId',\n", " 'player_recipient',\n", " 'player_recipient_id',\n", " 'CountPasses'\n", " ]\n", "\n", "##\n", "df_passing_network_grouped = df_passing_network_grouped.sort_values(['MatchID', 'player_id'], ascending=[True, True])\n", "\n", "##\n", "df_passing_network_grouped.head(10)" ] }, { "cell_type": "code", "execution_count": 237, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(1336, 11)" ] }, "execution_count": 237, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_passing_network_grouped.shape" ] }, { "cell_type": "code", "execution_count": 238, "metadata": {}, "outputs": [], "source": [ "# Select columns of interest\n", "\n", "## Define columns\n", "cols = ['Match',\n", " 'player_id',\n", " 'LastName',\n", " 'Pass_X',\n", " 'Pass_Y'\n", " ]\n", "\n", "##\n", "df_passing_network_avg_pass = df_passing_network[cols]" ] }, { "cell_type": "code", "execution_count": 239, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
Matchplayer_idLastNameavg_location_pass_xavg_location_pass_y
003/10/2021: Crystal Palace (2) vs. (2) Leicest...39155.0Lallana47.253.7
103/10/2021: Crystal Palace (2) vs. (2) Leicest...40836.0Guaita13.247.0
203/10/2021: Crystal Palace (2) vs. (2) Leicest...50175.0Welbeck65.881.6
303/10/2021: Crystal Palace (2) vs. (2) Leicest...50471.0McArthur55.767.8
403/10/2021: Crystal Palace (2) vs. (2) Leicest...54861.0Benteke83.646.8
503/10/2021: Crystal Palace (2) vs. (2) Leicest...55037.0Kouyaté38.820.5
603/10/2021: Crystal Palace (2) vs. (2) Leicest...55494.0Ward49.014.6
703/10/2021: Crystal Palace (2) vs. (2) Leicest...60307.0Groß48.549.3
803/10/2021: Crystal Palace (2) vs. (2) Leicest...61933.0Duffy27.838.6
903/10/2021: Crystal Palace (2) vs. (2) Leicest...66975.0Milivojevic54.650.1
1003/10/2021: Crystal Palace (2) vs. (2) Leicest...78916.0Burn32.776.7
1103/10/2021: Crystal Palace (2) vs. (2) Leicest...80146.0Ayew62.122.1
1203/10/2021: Crystal Palace (2) vs. (2) Leicest...82403.0Zaha72.783.2
1303/10/2021: Crystal Palace (2) vs. (2) Leicest...83299.0Dunk32.765.9
1403/10/2021: Crystal Palace (2) vs. (2) Leicest...86417.0Schlupp55.460.8
1503/10/2021: Crystal Palace (2) vs. (2) Leicest...111478.0Veltman48.520.5
1603/10/2021: Crystal Palace (2) vs. (2) Leicest...115382.0Maupay56.646.1
1703/10/2021: Crystal Palace (2) vs. (2) Leicest...116216.0Trossard56.945.6
1803/10/2021: Crystal Palace (2) vs. (2) Leicest...174874.0Andersen42.245.1
1903/10/2021: Crystal Palace (2) vs. (2) Leicest...179268.0Cucurella51.389.6
\n", "
" ], "text/plain": [ " Match player_id LastName \\\n", "0 03/10/2021: Crystal Palace (2) vs. (2) Leicest... 39155.0 Lallana \n", "1 03/10/2021: Crystal Palace (2) vs. (2) Leicest... 40836.0 Guaita \n", "2 03/10/2021: Crystal Palace (2) vs. (2) Leicest... 50175.0 Welbeck \n", "3 03/10/2021: Crystal Palace (2) vs. (2) Leicest... 50471.0 McArthur \n", "4 03/10/2021: Crystal Palace (2) vs. (2) Leicest... 54861.0 Benteke \n", "5 03/10/2021: Crystal Palace (2) vs. (2) Leicest... 55037.0 Kouyaté \n", "6 03/10/2021: Crystal Palace (2) vs. (2) Leicest... 55494.0 Ward \n", "7 03/10/2021: Crystal Palace (2) vs. (2) Leicest... 60307.0 Groß \n", "8 03/10/2021: Crystal Palace (2) vs. (2) Leicest... 61933.0 Duffy \n", "9 03/10/2021: Crystal Palace (2) vs. (2) Leicest... 66975.0 Milivojevic \n", "10 03/10/2021: Crystal Palace (2) vs. (2) Leicest... 78916.0 Burn \n", "11 03/10/2021: Crystal Palace (2) vs. (2) Leicest... 80146.0 Ayew \n", "12 03/10/2021: Crystal Palace (2) vs. (2) Leicest... 82403.0 Zaha \n", "13 03/10/2021: Crystal Palace (2) vs. (2) Leicest... 83299.0 Dunk \n", "14 03/10/2021: Crystal Palace (2) vs. (2) Leicest... 86417.0 Schlupp \n", "15 03/10/2021: Crystal Palace (2) vs. (2) Leicest... 111478.0 Veltman \n", "16 03/10/2021: Crystal Palace (2) vs. (2) Leicest... 115382.0 Maupay \n", "17 03/10/2021: Crystal Palace (2) vs. (2) Leicest... 116216.0 Trossard \n", "18 03/10/2021: Crystal Palace (2) vs. (2) Leicest... 174874.0 Andersen \n", "19 03/10/2021: Crystal Palace (2) vs. (2) Leicest... 179268.0 Cucurella \n", "\n", " avg_location_pass_x avg_location_pass_y \n", "0 47.2 53.7 \n", "1 13.2 47.0 \n", "2 65.8 81.6 \n", "3 55.7 67.8 \n", "4 83.6 46.8 \n", "5 38.8 20.5 \n", "6 49.0 14.6 \n", "7 48.5 49.3 \n", "8 27.8 38.6 \n", "9 54.6 50.1 \n", "10 32.7 76.7 \n", "11 62.1 22.1 \n", "12 72.7 83.2 \n", "13 32.7 65.9 \n", "14 55.4 60.8 \n", "15 48.5 20.5 \n", "16 56.6 46.1 \n", "17 56.9 45.6 \n", "18 42.2 45.1 \n", "19 51.3 89.6 " ] }, "execution_count": 239, "metadata": {}, "output_type": "execute_result" } ], "source": [ "#\n", "\n", "##\n", "df_passing_network_avg_pass_grouped = (df_passing_network_avg_pass \n", " .groupby(['Match',\n", " 'player_id',\n", " 'LastName',\n", " ])\n", " .agg({'Pass_X': ['mean'],\n", " 'Pass_Y': ['mean']\n", " })\n", " )\n", "\n", "##\n", "df_passing_network_avg_pass_grouped.columns = df_passing_network_avg_pass_grouped.columns.droplevel(level=0)\n", "\n", "##\n", "df_passing_network_avg_pass_grouped = df_passing_network_avg_pass_grouped.reset_index()\n", "\n", "## \n", "df_passing_network_avg_pass_grouped.columns = ['Match',\n", " 'player_id',\n", " 'LastName',\n", " 'avg_location_pass_x',\n", " 'avg_location_pass_y'\n", " ]\n", "\n", "##\n", "df_passing_network_avg_pass_grouped['avg_location_pass_x'] = df_passing_network_avg_pass_grouped['avg_location_pass_x'].round(decimals=1)\n", "df_passing_network_avg_pass_grouped['avg_location_pass_y'] = df_passing_network_avg_pass_grouped['avg_location_pass_y'].round(decimals=1)\n", "\n", "##\n", "#df_passing_network_avg_pass_grouped = df_passing_network_avg_pass_grouped.sort_values(['full_fixture_date', 'player_name'], ascending=[True, True])\n", "\n", "##\n", "df_passing_network_avg_pass_grouped.head(20)" ] }, { "cell_type": "code", "execution_count": 240, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(56, 5)" ] }, "execution_count": 240, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_passing_network_avg_pass_grouped.shape" ] }, { "cell_type": "code", "execution_count": 241, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
MatchMatchIDteam_idplayer_idPassToFromLastNamePassRecipientLastNamePassRecipientIdplayer_recipientplayer_recipient_idCountPasses
32803/10/2021: Crystal Palace (2) vs. (2) Leicest...f22103243639155.0Lallana - AndersenLallanaAndersen174874.0Andersen174874.04
\n", "
" ], "text/plain": [ " Match MatchID team_id \\\n", "328 03/10/2021: Crystal Palace (2) vs. (2) Leicest... f2210324 36 \n", "\n", " player_id PassToFrom LastName PassRecipientLastName \\\n", "328 39155.0 Lallana - Andersen Lallana Andersen \n", "\n", " PassRecipientId player_recipient player_recipient_id CountPasses \n", "328 174874.0 Andersen 174874.0 4 " ] }, "execution_count": 241, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_passing_network_grouped.head(1)" ] }, { "cell_type": "code", "execution_count": 242, "metadata": {}, "outputs": [], "source": [ "# Join the Events DataFrame to the Matches DataFrame\n", "df_pass_network_final = pd.merge(df_passing_network_grouped, df_passing_network_avg_pass_grouped, left_on=['Match', 'player_recipient_id'], right_on=['Match', 'player_id'])\n", "#df_pass_network_final = pd.merge(df_passing_network_grouped, df_passing_network_avg_pass_grouped, left_on=['Match', 'player_recipient'], right_on=['Match', 'LastName'])" ] }, { "cell_type": "code", "execution_count": 243, "metadata": {}, "outputs": [], "source": [ "## Rename columns\n", "df_pass_network_final = df_pass_network_final.rename(columns={'LastName_x': 'LastName',\n", " #'LastName_y': 'LastName'\n", " }\n", " )" ] }, { "cell_type": "code", "execution_count": 244, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
MatchMatchIDteam_idplayer_id_xPassToFromLastNamePassRecipientLastNamePassRecipientIdplayer_recipientplayer_recipient_idCountPassesplayer_id_yLastName_yavg_location_pass_xavg_location_pass_y
003/10/2021: Crystal Palace (2) vs. (2) Leicest...f22103243639155.0Lallana - AndersenLallanaAndersen174874.0Andersen174874.04174874.0Andersen42.245.1
103/10/2021: Crystal Palace (2) vs. (2) Leicest...f22103243140836.0Guaita - AndersenGuaitaAndersen174874.0Andersen174874.02174874.0Andersen42.245.1
203/10/2021: Crystal Palace (2) vs. (2) Leicest...f22103243150471.0McArthur - AndersenMcArthurAndersen174874.0Andersen174874.01174874.0Andersen42.245.1
303/10/2021: Crystal Palace (2) vs. (2) Leicest...f22103243155494.0Ward - AndersenWardAndersen174874.0Andersen174874.01174874.0Andersen42.245.1
403/10/2021: Crystal Palace (2) vs. (2) Leicest...f22103243660307.0Groß - AndersenGroßAndersen174874.0Andersen174874.04174874.0Andersen42.245.1
\n", "
" ], "text/plain": [ " Match MatchID team_id \\\n", "0 03/10/2021: Crystal Palace (2) vs. (2) Leicest... f2210324 36 \n", "1 03/10/2021: Crystal Palace (2) vs. (2) Leicest... f2210324 31 \n", "2 03/10/2021: Crystal Palace (2) vs. (2) Leicest... f2210324 31 \n", "3 03/10/2021: Crystal Palace (2) vs. (2) Leicest... f2210324 31 \n", "4 03/10/2021: Crystal Palace (2) vs. (2) Leicest... f2210324 36 \n", "\n", " player_id_x PassToFrom LastName PassRecipientLastName \\\n", "0 39155.0 Lallana - Andersen Lallana Andersen \n", "1 40836.0 Guaita - Andersen Guaita Andersen \n", "2 50471.0 McArthur - Andersen McArthur Andersen \n", "3 55494.0 Ward - Andersen Ward Andersen \n", "4 60307.0 Groß - Andersen Groß Andersen \n", "\n", " PassRecipientId player_recipient player_recipient_id CountPasses \\\n", "0 174874.0 Andersen 174874.0 4 \n", "1 174874.0 Andersen 174874.0 2 \n", "2 174874.0 Andersen 174874.0 1 \n", "3 174874.0 Andersen 174874.0 1 \n", "4 174874.0 Andersen 174874.0 4 \n", "\n", " player_id_y LastName_y avg_location_pass_x avg_location_pass_y \n", "0 174874.0 Andersen 42.2 45.1 \n", "1 174874.0 Andersen 42.2 45.1 \n", "2 174874.0 Andersen 42.2 45.1 \n", "3 174874.0 Andersen 42.2 45.1 \n", "4 174874.0 Andersen 42.2 45.1 " ] }, "execution_count": 244, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_pass_network_final.head()" ] }, { "cell_type": "code", "execution_count": 245, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(1336, 15)" ] }, "execution_count": 245, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_pass_network_final.shape" ] }, { "cell_type": "code", "execution_count": 246, "metadata": {}, "outputs": [], "source": [ "df_pass_network_final.to_csv(os.path.join(data_dir_opta, 'engineered', 'F24', 'f24-passing-network-merged.csv'), index=None, header=True)" ] }, { "cell_type": "code", "execution_count": 247, "metadata": {}, "outputs": [], "source": [ "df_pass_network_final.to_csv('test2.csv')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "---\n", "\n", "\n", "\n", "## 5. Export Final DataFrames" ] }, { "cell_type": "code", "execution_count": 106, "metadata": {}, "outputs": [], "source": [ "# Export DataFrames\n", "\n", "## Aggregated data\n", "df_cry_lei_agg.to_csv(os.path.join(data_dir_opta, 'engineered', 'F24', 'f24-8-2021-2210324-event_agg.csv'), index=None, header=True)\n", "df_cry_bri_agg.to_csv(os.path.join(data_dir_opta, 'engineered', 'F24', 'f24-8-2021-2210334-event_agg.csv'), index=None, header=True)\n", "\n", "## Event data\n", "df_cry_lei_events.to_csv(os.path.join(data_dir_opta, 'engineered', 'F24', 'f24-8-2021-2210324-eventdetails.csv'), index=None, header=True)\n", "df_cry_bri_events.to_csv(os.path.join(data_dir_opta, 'engineered', 'F24', 'f24-8-2021-2210334-eventdetails.csv'), index=None, header=True)\n", "df_events_merged.to_csv(os.path.join(data_dir_opta, 'engineered', 'F24', 'f24-eventdetails-merged.csv'), index=None, header=True)\n", "df_passing_matrix.to_csv(os.path.join(data_dir_opta, 'engineered', 'F24', 'f24-passing-matrix-merged.csv'), index=None, header=True)\n", "df_pass_network_final.to_csv(os.path.join(data_dir_opta, 'engineered', 'F24', 'f24-passing-network-merged.csv'), index=None, header=True)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "---\n", "\n", "\n", "\n", "## 6. Summary\n", "This notebook engineer parsed [Opta data](https://www.statsperform.com/opta/) by [Stats Perform](https://www.statsperform.com/) using [pandas](http://pandas.pydata.org/)." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "---\n", "\n", "\n", "\n", "## 7. Next Steps\n", "The next stage is to visualise this data in Tableau and analyse the findings, to be presented in a deck." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "---\n", "\n", "\n", "\n", "## 8. References\n", "* [Opta data](https://www.statsperform.com/opta/) by [Stats Perform](https://www.statsperform.com/) data" ] }, { "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 (ipykernel)", "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": "40px", "left": "1118px", "right": "20px", "top": "-7px", "width": "489px" }, "types_to_exclude": [ "module", "function", "builtin_function_or_method", "instance", "_Feature" ], "varInspector_section_display": "none", "window_display": true } }, "nbformat": 4, "nbformat_minor": 2 }