{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"#  <center> Horse racing - Analysis of speed and jockey's decsions </center>\n\n### Note Oct 2, 2022: Thanks to [Gabriel Beguerie](https://www.kaggle.com/gabrielbeguerie) suggestions, I changed the distance calculation using [geopy](https://geopy.readthedocs.io/en/stable/#module-geopy.distance) package.\n\n\n## Outline of this analysis\n\n\n<a id=\"toc\"></a>\n\n- [1. Data description](#1)\n\n    \n    \n- [2. Data preparation](#2)\n    - 2.1 calculate distance between every latitude and longitude data common collection of point (trakus_index)\n    - 2.2 calculate the speed of every horse in a race\n\n\n- [3. Speed analysis](#3)\n    - 3.1 how jockeys made their decisions that lead their wins: analysis of Javier Castellano's 2 races\n\n\n\n    \n","metadata":{"execution":{"iopub.status.busy":"2022-09-25T09:18:30.335498Z","iopub.execute_input":"2022-09-25T09:18:30.335954Z","iopub.status.idle":"2022-09-25T09:18:30.349475Z","shell.execute_reply.started":"2022-09-25T09:18:30.335844Z","shell.execute_reply":"2022-09-25T09:18:30.348170Z"}}},{"cell_type":"code","source":"import pandas as pd\nimport numpy as np\nimport os\nimport gc\nimport copy\nimport sys\nfrom pathlib import Path\n\nimport json\nimport joblib\n\n\nimport matplotlib.pyplot as plt\nimport matplotlib.lines as mlines\nimport statsmodels.api as sm\nimport seaborn as sns\n\nimport pyarrow.parquet as pq\nimport pyarrow as pa","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2022-10-02T13:41:44.795755Z","iopub.execute_input":"2022-10-02T13:41:44.796228Z","iopub.status.idle":"2022-10-02T13:41:46.341181Z","shell.execute_reply.started":"2022-10-02T13:41:44.796177Z","shell.execute_reply":"2022-10-02T13:41:46.339762Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<a id=\"1\"></a>\n\n# <center>Data Description</center>\n\n[back to top](#toc)\n\n\n\n\n\n| field name  | field description   |\n| ------------ | ------------ |\n|track_id | 3 character id for the track the race took place at. AQU -Aqueduct, BEL - Belmont, SAR - Saratoga.|\n|race_date | date the race took place. YYYY-MM-DD.|\n|race_number | Number of the race. Passed as 3 characters but can be cast or converted to int for this data set.|\n|program_number | Program number of the horse in the race passed as 3 characters. Should remain 3 characters as it isn't limited to just numbers. Is essentially the unique identifier of the horse in the race.|\n|weight_carried | An integer of the weight carried by the horse in the race.|\n|jockey | Name of the jockey on the horse in the race. 50 character max.|\n|odds | Odds to win the race passed as an integer. Divide by 100 to derive the odds to 1. Example - 1280 would be 12.8-1.|\n|position_at_finish | An integer of the horse's finishing position. (added to the dataset 9/8/22)|\n|distance_id | Distance of the race in furlongs passed as an integer. Example - 600 would be 6 furlongs.|\n|course_type | The course the race was run over passed as one character. M - Hurdle, D - Dirt, O - Outer turf, I - Inner turf, T - turf.\n|track_condition | The condition of the course the race was run on passed as three characters. YL - Yielding, FM - Firm, SY - Sloppy, GD - Good, FT - Fast, MY - Muddy, SF - Soft.|\n|run_up_distance | Distance in feet of the gate to the start of the race passed as an integer.|\n|race_type | The classification of the race passed as as five characters. STK - Stakes, WCL - Waiver Claiming, WMC - Waiver Maiden Claiming, SST - Starter Stakes, SHP - Starter Handicap, CLM - Claiming, STR - Starter Allowance, AOC - Allowance Optionl Claimer, SOC - Starter Optional Claimer, MCL - Maiden Claiming, ALW - Allowance, MSW - Maiden Special Weight.|\n|purse | Purse in US dollars of the race passed as an money with two decimal places.|\n|post_time | Time of day the race began passed as 5 character. Example - 01220 would be 12:20.|\n|trakus_index | The common collection of point of the lat / long of the horse in the race passed as an integer. From what we can tell, it's collected every 0.25 seconds.|\n|latitude | The latitude of the horse in the race passed as a float.|\n|longitude | The longitude of the horse in the race passed as a float.|\n|*race_id|unique number for race_date + race_number  combination.|\n|*race_horse_id|unique number for race_date + race_number + program_number combination.|","metadata":{}},{"cell_type":"code","source":"%%time\ndf = pd.read_parquet('/kaggle/input/derby-2022-merge-and-convert-data-to-parquet-file/nyra_2019_complete.parquet')","metadata":{"_kg_hide-input":true,"_kg_hide-output":true,"execution":{"iopub.status.busy":"2022-10-02T13:41:49.304670Z","iopub.execute_input":"2022-10-02T13:41:49.306049Z","iopub.status.idle":"2022-10-02T13:41:52.561165Z","shell.execute_reply.started":"2022-10-02T13:41:49.305998Z","shell.execute_reply":"2022-10-02T13:41:52.560277Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"race_type_dict =   {  'STK': 'Stakes', \n                      'WCL': 'Waiver Claiming', \n                      'WMC': 'Waiver Maiden Claiming', \n                      'SST': 'Starter Stakes', \n                      'SHP': 'Starter Handicap',\n                      'CLM': 'Claiming', \n                      'STR': 'Starter Allowance', \n                      'AOC': 'Allowance Optionl Claimer', \n                      'SOC': 'Starter Optional Claimer', \n                      'MCL': 'Maiden Claiming', \n                      'ALW': 'Allowance', \n                      'MSW': 'Maiden Special Weight'\n                      }\n\ntrack_id_dict = dict(AQU = 'Aqueduct', BEL = 'Belmont', SAR = 'Saratoga')\ncourse_type_dict = dict(M = 'Hurdle', D = 'Dirt', O = 'Outer turf', I = 'Inner turf', T = 'turf')\ntrack_condition_dict =  dict(YL = 'Yielding', FM ='Firm', SY = 'Sloppy', GD = 'Good', FT = 'Fast', MY = 'Muddy', SF = 'Soft')\n\ndf['race_type'] = df['race_type'].map(race_type_dict)\ndf['track_id'] = df['track_id'].map(track_id_dict)\ndf['course_type'] = df['course_type'].map(course_type_dict)\n\ndf['track_condition']=df['track_condition'].apply(lambda x:x.replace(\" \", ''))\ndf['track_condition'] = df['track_condition'].map(track_condition_dict)\n","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2022-10-02T13:41:52.562493Z","iopub.execute_input":"2022-10-02T13:41:52.563379Z","iopub.status.idle":"2022-10-02T13:41:56.777088Z","shell.execute_reply.started":"2022-10-02T13:41:52.563342Z","shell.execute_reply":"2022-10-02T13:41:56.775733Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#df.sort_values(by=['race_horse_id', 'trakus_index'], ascending=[True]*2, inplace=True)","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2022-10-02T13:42:14.376138Z","iopub.execute_input":"2022-10-02T13:42:14.376640Z","iopub.status.idle":"2022-10-02T13:42:14.382550Z","shell.execute_reply.started":"2022-10-02T13:42:14.376598Z","shell.execute_reply":"2022-10-02T13:42:14.381392Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"\n\n<a id=\"2\"></a>\n\n# <center>Data preparation</center>\n\n[back to top](#toc)\n\n\nIn this section, we calculate the distance (in meters) between every two trakus_index (i.e. location data collection), then divide the distance by 0.25 seconds to get the speed. The speed data will be used to analysis jockey's decisions.\n","metadata":{}},{"cell_type":"code","source":"#https://stackoverflow.com/questions/19412462/getting-distance-between-two-points-based-on-latitude-longitude\nfrom math import sin, cos, sqrt, atan2\n#returns the distance in meters\ndef cal_distance(data):\n    \"\"\"\n    data is a pd.Series, must have 'latitude', 'longitude', 'latitude2', 'longitude2'\n    \"\"\"\n    if (data is None)|(data is np.nan):\n        return 0\n\n    R = 6373.0 ## approximate radius of earth in km\n\n    lat1, lon1, lat2, lon2 = data[['latitude', 'longitude', 'latitude2', 'longitude2']].values\n  \n\n    dlon = lon2 - lon1\n    dlat = lat2 - lat1\n    a = (sin(dlat/2))**2 + cos(lat1) * cos(lat2) * (sin(dlon/2))**2\n    c = 2 * atan2(sqrt(a), sqrt(1-a))\n    distance = R * c*1000\n    return distance","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2022-10-02T13:42:15.739366Z","iopub.execute_input":"2022-10-02T13:42:15.739839Z","iopub.status.idle":"2022-10-02T13:42:15.748825Z","shell.execute_reply.started":"2022-10-02T13:42:15.739798Z","shell.execute_reply":"2022-10-02T13:42:15.747380Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#https://geopy.readthedocs.io/en/stable/#module-geopy.distance\nfrom geopy.distance import distance as GO_DIS\n","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2022-10-02T13:42:17.002595Z","iopub.execute_input":"2022-10-02T13:42:17.003052Z","iopub.status.idle":"2022-10-02T13:42:17.009409Z","shell.execute_reply.started":"2022-10-02T13:42:17.003017Z","shell.execute_reply":"2022-10-02T13:42:17.007748Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<a id=\"3\"></a>\n\n# <center>Speed analysis</center>\n\n[back to top](#toc)\n\n\n\nWe selected races participated by `Javier Castellano` as he had highest win rate (over 20%) and highest place rate (55% place rate).\n\n>- win rate as percentage of races a jockey finished in 1st position out of all the races he participated in.\n>- place rate as percentage of races a jockey finished in 1st, 2nd, or 3rd position out of all the races he perticipated in.\n","metadata":{}},{"cell_type":"code","source":"def plot_track(data, figsize=(14, 8), caption=''):\n    plt.figure(figsize=(14, 8), dpi=100, )\n\n    i = 0\n    for pn in data['program_number'].unique():\n        plt.scatter('latitude', 'longitude',\n                    data=data[data['program_number']==pn],\n                    s=20, c=colors[i], label='',  marker='o') \n\n        i = i + 1\n        if i >7:\n            break\n\n    plt.scatter('latitude', 'longitude',\n                        data=data[(data['program_number']==pn) & (data['trakus_index']<5)],\n                        s=300, c='black', label='',  marker='*')         \n\n    plt.title(caption,  fontsize=14, loc='left')\n\n    plt.grid(visible=True, which='major', axis='both', color='lightgray', linestyle='-', linewidth=0.1)\n    plt.gca().spines[['top', 'right']].set_visible(False)\n    plt.gca().spines[['bottom', 'left']].set_edgecolor('whitesmoke')\n\n    plt.yticks(fontsize=9, )#rotation=90\n    plt.xticks(fontsize=9, )#rotation=90\n    plt.tight_layout()\n    plt.show()","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2022-10-02T13:42:18.542446Z","iopub.execute_input":"2022-10-02T13:42:18.543359Z","iopub.status.idle":"2022-10-02T13:42:18.553970Z","shell.execute_reply.started":"2022-10-02T13:42:18.543317Z","shell.execute_reply":"2022-10-02T13:42:18.552777Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def lines(data, figsize=(15, 8), caption='', labels=[]):\n    plt.figure(figsize=figsize)#dpi=100\n    colors = ['lightseagreen', 'salmon', 'lightskyblue', 'mediumseagreen', 'sandybrown', 'lightslategray', 'wheat', 'crimson']\n    mcolors = ['teal', 'tomato', 'skyblue', 'mediumseagreen', 'peru', 'slategray', 'tan',  'firebrick']\n    \n    for i in range(data.shape[1]):\n        plt.plot(data.index, data.iloc[:, i], marker='', markerfacecolor=mcolors[i], markersize=2, color=colors[i], linewidth=2, label=labels[i])\n        plt.text(data.iloc[:, i].dropna().size + 1, data.iloc[:, i].dropna().values[-1], labels[i], fontsize=11, color=mcolors[i])\n\n    #plt.legend()\n    plt.title(caption,  fontsize=14, loc='left')\n\n    plt.grid(visible=True, which='major', axis='both', color='lightgray', linestyle='-', linewidth=0.2)\n    plt.gca().spines[['top', 'right']].set_visible(False)\n    plt.gca().spines[['bottom', 'left']].set_edgecolor('whitesmoke')\n    \n    plt.yticks(fontsize=9, )#rotation=90\n    plt.xticks(fontsize=9, )#rotation=90\n    plt.tight_layout()\n    plt.show()\n    ","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2022-10-02T13:42:19.284224Z","iopub.execute_input":"2022-10-02T13:42:19.284894Z","iopub.status.idle":"2022-10-02T13:42:19.296143Z","shell.execute_reply.started":"2022-10-02T13:42:19.284857Z","shell.execute_reply":"2022-10-02T13:42:19.294669Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#### First, we look at a race in which `Javier Castellano` did not win. We select the 1st race on 2019-03-09. The race was held on `Aqueduct` track and the distance was 6 furlongs. \n\nFrom the track plot, we noitced that one jockey in the race did not finish the race (the trakus_index data is missing the last few collection points). The speed line chart further confirms this information. More over, it is clear from the speed chart that the horse (and jockey) that did not finish the race was slower than other horses from the begining. \n\nInterestingly, the jocky (and horse) finished 1st place (i.e. won the race) was not always faster than other horse throughout the race. \n","metadata":{}},{"cell_type":"code","source":"df[(df['jockey']=='Javier Castellano') & (df['distance_id']==600) \\\n   & (df['position_at_finish']<3)& (df['race_id']>286)\\\n   & (df['course_type']=='Dirt')\\\n  ].head(400)\n\n#& (df['track_condition']=='Fast')","metadata":{"_kg_hide-input":true,"_kg_hide-output":true,"execution":{"iopub.status.busy":"2022-10-02T13:42:20.955625Z","iopub.execute_input":"2022-10-02T13:42:20.956106Z","iopub.status.idle":"2022-10-02T13:42:21.659056Z","shell.execute_reply.started":"2022-10-02T13:42:20.956064Z","shell.execute_reply":"2022-10-02T13:42:21.657929Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"colors = ['lightseagreen', 'salmon', 'lightskyblue', 'mediumseagreen', 'sandybrown', 'lightslategray', 'wheat', 'crimson']\nmcolors = ['teal', 'tomato', 'skyblue', 'mediumseagreen', 'peru', 'slategray', 'tan',  'firebrick']","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2022-10-02T13:42:24.035605Z","iopub.execute_input":"2022-10-02T13:42:24.036137Z","iopub.status.idle":"2022-10-02T13:42:24.043277Z","shell.execute_reply.started":"2022-10-02T13:42:24.036082Z","shell.execute_reply":"2022-10-02T13:42:24.041634Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"data = df[df['race_id']==286].copy(deep=True)\ndata.sort_values(by=['race_horse_id', 'trakus_index'], ascending=[True]*2, inplace=True)\n\ncaption =f\"race type: {data.iloc[0]['race_type']} - track: {data.iloc[0]['track_id']} - race date: {data.iloc[0]['race_date']} ({data.iloc[0]['race_number']}) - distance: {data.iloc[0]['distance_id']} - course: {data.iloc[0]['course_type']}\"\n\n\nplot_track(data, figsize=(14, 8), caption=caption)","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2022-10-02T13:42:25.428862Z","iopub.execute_input":"2022-10-02T13:42:25.429254Z","iopub.status.idle":"2022-10-02T13:42:25.961738Z","shell.execute_reply.started":"2022-10-02T13:42:25.429220Z","shell.execute_reply":"2022-10-02T13:42:25.960815Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"data_next = data[['race_horse_id','trakus_index','latitude','longitude']].groupby('race_horse_id').shift(-1)\ndata_next.columns = [f'{c}2' for c in data_next.columns]\ndata = pd.concat([data, data_next], axis=1)\n# data['distance'] = data.apply(lambda x: cal_distance(x), axis=1)\n# data['speed'] = data['distance']/0.25\n\ndata.dropna(how='any', inplace=True)\ndata['distance'] = data.apply(lambda x: GO_DIS(x[['latitude', 'longitude']].values,x[['latitude2', 'longitude2']].values).meters, axis=1)\ndata['speed'] = data['distance']/0.25","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2022-10-02T13:42:53.744147Z","iopub.execute_input":"2022-10-02T13:42:53.746447Z","iopub.status.idle":"2022-10-02T13:42:55.694155Z","shell.execute_reply.started":"2022-10-02T13:42:53.746323Z","shell.execute_reply":"2022-10-02T13:42:55.692846Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"cs = data.iloc[:-1, ].pivot(index='trakus_index', columns=['program_number', 'jockey', 'position_at_finish'], values='speed')\ncs.columns = [f'{b} (pn:{a},plc:{c})' for a,b,c in cs.columns]\nlines(cs, figsize=(18, 6.5), caption='Progression of speed of each jockey in a race. (pn: program_number, plc: position_at_finish)', labels=cs.columns.tolist())","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2022-10-02T13:42:57.885870Z","iopub.execute_input":"2022-10-02T13:42:57.887180Z","iopub.status.idle":"2022-10-02T13:42:58.173166Z","shell.execute_reply.started":"2022-10-02T13:42:57.887128Z","shell.execute_reply":"2022-10-02T13:42:58.171975Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"cs = data[data['position_at_finish']<5].pivot(index='trakus_index', columns=['program_number', 'jockey', 'position_at_finish'], values='speed')\ncs.columns = [f'{b} (pn:{a},plc:{c})' for a,b,c in cs.columns]\nlines(cs, figsize=(18, 6.5), caption='Progression of speed of each jockey in a race - top 4 jockeys. (pn: program_number, plc: position_at_finish)', labels=cs.columns.tolist())","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2022-10-02T13:43:01.066852Z","iopub.execute_input":"2022-10-02T13:43:01.068637Z","iopub.status.idle":"2022-10-02T13:43:01.325585Z","shell.execute_reply.started":"2022-10-02T13:43:01.068511Z","shell.execute_reply":"2022-10-02T13:43:01.324408Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#### Then, we look at a race in which `Javier Castellano` finished at 2nd place. We select the 8th race on 2019-04-19. The race was held on `Aqueduct` track and the distance was 6 furlongs. \n\nSince the 2 races were on the same track,  same distance, same track condition, and at same starting point, the jockeys' speed jockey's decisions are comparable.\n\nIn this race, all horses finished the race. Based on the speed lines, this race seemd to be more fierce than the previous one.\n","metadata":{}},{"cell_type":"code","source":"data1 = df[df['race_id']==487].copy(deep=True)\ndata1.sort_values(by=['race_horse_id', 'trakus_index'], ascending=[True]*2, inplace=True)\n\ncaption =f\"race type: {data1.iloc[0]['race_type']} - track: {data1.iloc[0]['track_id']} - \\\nrace date: {data1.iloc[0]['race_date']} ({data1.iloc[0]['race_number']}) - \\\ndistance: {data1.iloc[0]['distance_id']} - course: {data1.iloc[0]['course_type']}\"\n\n\nplot_track(data1, figsize=(14, 8), caption=caption)","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2022-10-02T13:43:10.138569Z","iopub.execute_input":"2022-10-02T13:43:10.139102Z","iopub.status.idle":"2022-10-02T13:43:10.504903Z","shell.execute_reply.started":"2022-10-02T13:43:10.139064Z","shell.execute_reply":"2022-10-02T13:43:10.503714Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"data_next1 = data1[['race_horse_id','trakus_index','latitude','longitude']].groupby('race_horse_id').shift(-1)\ndata_next1.columns = [f'{c}2' for c in data_next1.columns]\ndata1 = pd.concat([data1, data_next1], axis=1)\n# data1['distance'] = data1.apply(lambda x: cal_distance(x), axis=1)\n# data1['speed'] = data1['distance']/0.25\n\ndata1.dropna(how='any', inplace=True)\ndata1['distance'] = data1.apply(lambda x: GO_DIS(x[['latitude', 'longitude']].values,x[['latitude2', 'longitude2']].values).meters, axis=1)\ndata1['speed'] = data1['distance']/0.25","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2022-10-02T13:43:33.405081Z","iopub.execute_input":"2022-10-02T13:43:33.405529Z","iopub.status.idle":"2022-10-02T13:43:35.594949Z","shell.execute_reply.started":"2022-10-02T13:43:33.405490Z","shell.execute_reply":"2022-10-02T13:43:35.593673Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"cs1 = data1.iloc[:-1, ].pivot(index='trakus_index', columns=['program_number', 'jockey', 'position_at_finish'], values='speed')\ncs1.columns = [f'{b} (pn:{a},plc:{c})' for a,b,c in cs1.columns]\nlines(cs1, figsize=(18, 6.5), \n      caption='Progression of speed of each jockey in a race. (pn: program_number, plc: position_at_finish)', \n      labels=cs1.columns.tolist())","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2022-10-02T13:43:36.785397Z","iopub.execute_input":"2022-10-02T13:43:36.785834Z","iopub.status.idle":"2022-10-02T13:43:37.075397Z","shell.execute_reply.started":"2022-10-02T13:43:36.785801Z","shell.execute_reply":"2022-10-02T13:43:37.074257Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"cs1 = data1[data1['position_at_finish']<4].pivot(index='trakus_index', columns=['program_number', 'jockey', 'position_at_finish'], values='speed')\ncs1.columns = [f'{b} (pn:{a},plc:{c})' for a,b,c in cs1.columns]\nlines(cs1, figsize=(18, 6.5), caption='Progression of speed of each jockey in a race - top 3 jockeys. (pn: program_number, plc: position_at_finish)', labels=cs1.columns.tolist())","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2022-10-02T13:43:42.568703Z","iopub.execute_input":"2022-10-02T13:43:42.569087Z","iopub.status.idle":"2022-10-02T13:43:42.943434Z","shell.execute_reply.started":"2022-10-02T13:43:42.569056Z","shell.execute_reply":"2022-10-02T13:43:42.942447Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#### Finally, we compare `Javier Castellano`'s speed in the 2 races as well as the speed of the winners in the 2 races.\n\n`Javier Castellano` finished 4th position in the 1st race and 2nd in the 2nd race; his 'program_number' was 6 in both races which means exactly same starting point.  The speed lines show that the higher speed before `trak_index 150` could be the driving factor to winning.\n\n\n\nThe winner of the 1st race was Junior Alvarado and he did not race in the 2nd race; The winner of the 2nd race was Benjamin Hernandez and he was not in the 1st race.","metadata":{}},{"cell_type":"code","source":"cs2 = cs.merge(cs1, left_index=True, right_index=True, how='left')","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2022-10-02T13:43:46.740857Z","iopub.execute_input":"2022-10-02T13:43:46.741593Z","iopub.status.idle":"2022-10-02T13:43:46.753687Z","shell.execute_reply.started":"2022-10-02T13:43:46.741553Z","shell.execute_reply":"2022-10-02T13:43:46.752490Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"lines(cs2[['Javier Castellano (pn:6  ,plc:4)', 'Javier Castellano (pn:6  ,plc:2)']], figsize=(18, 6.5), \n      caption='Javier Castellano: speed in 2 races. (pn: program_number, plc: position_at_finish)', \n      labels=['1st race - finish position: 4', '2nd race - finish position: 2'])\n","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2022-10-02T13:43:48.567159Z","iopub.execute_input":"2022-10-02T13:43:48.567849Z","iopub.status.idle":"2022-10-02T13:43:49.079185Z","shell.execute_reply.started":"2022-10-02T13:43:48.567809Z","shell.execute_reply":"2022-10-02T13:43:49.078267Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"lines(cs2[['Junior Alvarado (pn:4  ,plc:1)', 'Benjamin Hernandez (pn:5  ,plc:1)']], figsize=(18, 6.5), \n      caption='Winners in the 2 races (pn: program_number, plc: position_at_finish)', \n      labels=['1st race: Junior Alvarado (pn:4  ,plc:1)', '2nd race: Benjamin Hernandez (pn:5  ,plc:1)'])\n","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2022-10-02T13:43:51.220659Z","iopub.execute_input":"2022-10-02T13:43:51.221343Z","iopub.status.idle":"2022-10-02T13:43:51.557610Z","shell.execute_reply.started":"2022-10-02T13:43:51.221304Z","shell.execute_reply":"2022-10-02T13:43:51.556267Z"},"trusted":true},"execution_count":null,"outputs":[]}]}