Skip to content

Instantly share code, notes, and snippets.

@903124
Created August 7, 2022 10:10
Show Gist options
  • Save 903124/6624b0e80420f7fe61488395eba73aff to your computer and use it in GitHub Desktop.
Save 903124/6624b0e80420f7fe61488395eba73aff to your computer and use it in GitHub Desktop.
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Here is a code demostrates how to merge tracking with event data with metrica sample data https://github.com/metrica-sports/sample-data as reference"
]
},
{
"cell_type": "code",
"execution_count": 136,
"metadata": {
"ExecuteTime": {
"end_time": "2022-08-07T07:16:21.618607Z",
"start_time": "2022-08-07T07:16:21.606607Z"
}
},
"outputs": [],
"source": [
"import pandas as pd\n",
"import numpy as np\n",
"import csv\n",
"import matplotlib.pyplot as plt"
]
},
{
"cell_type": "code",
"execution_count": 257,
"metadata": {
"ExecuteTime": {
"end_time": "2022-08-07T07:35:48.243495Z",
"start_time": "2022-08-07T07:35:48.228496Z"
}
},
"outputs": [],
"source": [
"def tracking_data_process(DATADIR):\n",
"\n",
" # First: deal with file headers so that we can get the player names correct\n",
" csvfile = open(DATADIR, 'r') # create a csv file reader\n",
" reader = csv.reader(csvfile) \n",
" teamnamefull = next(reader)[3].lower()\n",
" print(\"Reading team: %s\" % teamnamefull)\n",
" # construct column names\n",
" jerseys = [x for x in next(reader) if x != ''] # extract player jersey numbers from second row\n",
" columns = next(reader)\n",
" for i, j in enumerate(jerseys): # create x & y position column headers for each player\n",
" columns[i*2+3] = \"{}_x\".format(j)\n",
" columns[i*2+4] = \"{}_y\".format(j)\n",
" columns[-2] = \"ball_x\" # column headers for the x & y positions of the ball\n",
" columns[-1] = \"ball_y\"\n",
" # Second: read in tracking data and place into pandas Dataframe\n",
" tracking = pd.read_csv(DATADIR, names=columns, index_col='Frame', skiprows=3)\n",
" return tracking"
]
},
{
"cell_type": "code",
"execution_count": 284,
"metadata": {
"ExecuteTime": {
"end_time": "2022-08-07T09:56:52.908553Z",
"start_time": "2022-08-07T09:56:52.616917Z"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Reading team: home\n"
]
}
],
"source": [
"event_data = pd.read_csv('data/Sample_Game_1/Sample_Game_1_RawEventsData.csv')\n",
"tracking_data = tracking_data_process('data/Sample_Game_1/Sample_Game_1_RawTrackingData_Home_Team.csv')"
]
},
{
"cell_type": "code",
"execution_count": 285,
"metadata": {
"ExecuteTime": {
"end_time": "2022-08-07T09:56:53.201929Z",
"start_time": "2022-08-07T09:56:53.184366Z"
},
"scrolled": true
},
"outputs": [],
"source": [
"event_data = event_data[event_data['Period'] == 2].reset_index()\n",
"tracking_data = tracking_data[tracking_data['Period'] == 2].reset_index()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"While for sample data here is synchronized, imagine they are not e.g. offset by unknown amount for frames and we have to find the number out. Here the unknown frame is set to 30000"
]
},
{
"cell_type": "code",
"execution_count": 261,
"metadata": {
"ExecuteTime": {
"end_time": "2022-08-07T07:35:50.827323Z",
"start_time": "2022-08-07T07:35:50.812323Z"
}
},
"outputs": [],
"source": [
"unknown_frame_offset = 30000\n",
"\n",
"tracking_data['Frame'] += unknown_frame_offset"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Also tracking data will not have perfect agreement with event data location in real life so some random noise is added here."
]
},
{
"cell_type": "code",
"execution_count": 262,
"metadata": {
"ExecuteTime": {
"end_time": "2022-08-07T07:35:51.262118Z",
"start_time": "2022-08-07T07:35:51.243236Z"
}
},
"outputs": [],
"source": [
"tracking_data['ball_x'] += 0.005*np.random.random()\n",
"tracking_data['ball_y'] += 0.005*np.random.random()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Then it's the main body of script: for every passes in event data, get the (starting) event x-y location, then we try to merge and iterate with data so the distance between the ball and event location is minimized. When we select a random frame, the distance between event and ball location will be essentially randomized, but for the frame that are synchronized, the distance will become minized.\n",
"\n",
"While event data and tracking data can be unknown frames apart, typically tracking data provider will start the game not too long after the first frame, and therefore it can be used as an initial guess instead of guessing every possible time."
]
},
{
"cell_type": "code",
"execution_count": 264,
"metadata": {
"ExecuteTime": {
"end_time": "2022-08-07T07:35:55.479153Z",
"start_time": "2022-08-07T07:35:55.476152Z"
}
},
"outputs": [],
"source": [
"intial_guess = tracking_data['Frame'][0] - event_data['Start Frame'][0]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"During the iteration, the distance between event and ball location is stored. Typically the min and max search frame can be adjusted so to decrease amount of run time. Certain threshold can also be added to stop the script early when minimum is found (not implemented here)."
]
},
{
"cell_type": "code",
"execution_count": 271,
"metadata": {
"ExecuteTime": {
"end_time": "2022-08-07T07:37:26.299397Z",
"start_time": "2022-08-07T07:37:03.900371Z"
},
"scrolled": true
},
"outputs": [],
"source": [
"ball_dist = []\n",
"min_search_frame = 0\n",
"max_search_frame = 1000\n",
"for i in range(min_search_frame,max_search_frame):\n",
" temp_tracking_data = tracking_data.copy()\n",
" \n",
" temp_tracking_data['mergeFrame'] = temp_tracking_data['Frame'] - i - intial_guess\n",
" merged_data = pd.merge(event_data[event_data.Type == 'PASS'][['Start Frame','Start X','Start Y']],temp_tracking_data[['mergeFrame','ball_x','ball_y']],left_on='Start Frame',right_on='mergeFrame')\n",
" ball_avg_dist = np.sqrt((merged_data['ball_x'] - merged_data['Start X']) ** 2 + (merged_data['ball_y'] - merged_data['Start Y']) ** 2)\n",
" ball_dist.append(np.mean(ball_avg_dist))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"When we plot the distance we can find there is a sharp minimum at a certain frame"
]
},
{
"cell_type": "code",
"execution_count": 272,
"metadata": {
"ExecuteTime": {
"end_time": "2022-08-07T07:37:32.431695Z",
"start_time": "2022-08-07T07:37:32.335552Z"
}
},
"outputs": [
{
"data": {
"text/plain": [
"[<matplotlib.lines.Line2D at 0x1f915c54c10>]"
]
},
"execution_count": 272,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"image/png": "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\n",
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"plt.title('Distance between ball and event location vs frame')\n",
"plt.plot(np.arange(len(ball_dist)),ball_dist)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"After adding back initial guess and guess range we can get the synchronized frame we want"
]
},
{
"cell_type": "code",
"execution_count": 275,
"metadata": {
"ExecuteTime": {
"end_time": "2022-08-07T07:37:40.614310Z",
"start_time": "2022-08-07T07:37:40.604310Z"
}
},
"outputs": [
{
"data": {
"text/plain": [
"30000"
]
},
"execution_count": 275,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"intial_guess + min_search_frame + np.argmin(ball_dist)"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.8.5"
}
},
"nbformat": 4,
"nbformat_minor": 4
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment