{"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":"code","source":"import numpy as np\nimport pandas as pd\n\nimport matplotlib.pyplot as plt\nfrom math import pi","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2022-11-09T08:44:54.999026Z","iopub.execute_input":"2022-11-09T08:44:54.999515Z","iopub.status.idle":"2022-11-09T08:44:55.006022Z","shell.execute_reply.started":"2022-11-09T08:44:54.999477Z","shell.execute_reply":"2022-11-09T08:44:55.004593Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# load data\n\nrace = pd.read_csv(\"../input/big-data-derby-2022/nyra_race_table.csv\")\nstart = pd.read_csv(\"../input/big-data-derby-2022/nyra_start_table.csv\")\n","metadata":{"execution":{"iopub.status.busy":"2022-11-09T08:44:55.008510Z","iopub.execute_input":"2022-11-09T08:44:55.008972Z","iopub.status.idle":"2022-11-09T08:45:28.618317Z","shell.execute_reply.started":"2022-11-09T08:44:55.008930Z","shell.execute_reply":"2022-11-09T08:45:28.616976Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Add headings to 'start' dataframe\nstart.columns = [\"track_id\", \"race_date\", \"race_number\", \"program_number\", \"weight_carried\", \"jockey\", \"odd\", \"position_at_finish\"]","metadata":{"execution":{"iopub.status.busy":"2022-11-09T08:45:28.619762Z","iopub.execute_input":"2022-11-09T08:45:28.620192Z","iopub.status.idle":"2022-11-09T08:45:28.625410Z","shell.execute_reply.started":"2022-11-09T08:45:28.620154Z","shell.execute_reply":"2022-11-09T08:45:28.624415Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"rate_jockey = pd.merge(start, race, on=[\"track_id\",\"race_date\", \"race_number\" ], how=\"left\")\nrate_jockey = rate_jockey.loc[:,[\"jockey\", \"track_id\", \"distance_id\", \"course_type\", \"position_at_finish\"]]\nrate_jockey = rate_jockey.sort_values(\"jockey\")\nrate_jockey","metadata":{"execution":{"iopub.status.busy":"2022-11-09T08:45:28.627979Z","iopub.execute_input":"2022-11-09T08:45:28.628450Z","iopub.status.idle":"2022-11-09T08:45:28.690186Z","shell.execute_reply.started":"2022-11-09T08:45:28.628407Z","shell.execute_reply":"2022-11-09T08:45:28.688918Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"The amount of top 3 metals is what we are interested of looking at which we want to create a chart for total amount of metals received for the best 10 jockeys.","metadata":{}},{"cell_type":"code","source":"rate_jockey[\"First\"] = np.where( (rate_jockey.position_at_finish == 1), 1, 0)\nrate_jockey[\"Second\"] = np.where( (rate_jockey.position_at_finish == 2), 1, 0)\nrate_jockey[\"Third\"] = np.where( (rate_jockey.position_at_finish == 3), 1, 0)\n\njockey_by_metal = rate_jockey.groupby([\"jockey\"])[[\"First\", \"Second\", \"Third\"]].sum()\njockey_by_metal = jockey_by_metal.sort_values([\"First\", \"Second\", \"Third\"], ascending = False)\njockey_by_metal.head(10)","metadata":{"execution":{"iopub.status.busy":"2022-11-09T08:45:28.691935Z","iopub.execute_input":"2022-11-09T08:45:28.692256Z","iopub.status.idle":"2022-11-09T08:45:28.722972Z","shell.execute_reply.started":"2022-11-09T08:45:28.692228Z","shell.execute_reply":"2022-11-09T08:45:28.721255Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"1st place is what we care the most which now we want to analyze all jockey rating based on their first place only. First we want to consider top 10 jockeys who joined at least 10 games which has the highest winrate. ","metadata":{}},{"cell_type":"code","source":"rate_jockey[\"games\"] = 1\nwinrate_jockey = rate_jockey.groupby([\"jockey\"])[[\"First\", \"Second\", \"Third\", \"games\"]].sum()\nwinrate_jockey[\"win_rate\"] = winrate_jockey[\"First\"] / winrate_jockey[\"games\"]\nwinrate_jockey[\"win/loss_ratio\"] = (winrate_jockey[\"First\"] + winrate_jockey[\"Second\"]+ winrate_jockey[\"Third\"] )/ (winrate_jockey[\"games\"] - winrate_jockey[\"First\"] - winrate_jockey[\"Second\"] - winrate_jockey[\"Third\"])\n\nwinrate_10g_jockey = winrate_jockey[winrate_jockey[\"games\"] >= 10]\nwinrate_10g_jockey = winrate_10g_jockey.sort_values([\"win_rate\"], ascending = False)\nwinrate_10g_jockey.head(10)","metadata":{"execution":{"iopub.status.busy":"2022-11-09T08:45:28.724885Z","iopub.execute_input":"2022-11-09T08:45:28.725355Z","iopub.status.idle":"2022-11-09T08:45:28.754271Z","shell.execute_reply.started":"2022-11-09T08:45:28.725309Z","shell.execute_reply":"2022-11-09T08:45:28.753494Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Win_rate is calculated based on the number of first place divided by the number of games each jockey has played for. The win loss ratio is calculated by the number of times in top 3 divided by the games that are not in top 3. Win rate gives us a clear view on which jockey is most welling to win the game and win loss ratio is used to see the ratio of top 3 rate over a given period. If the value of the ratio is above 1 then we have higher than 50% of the chance to see this jockey make it into the top 3 positions. This chart shows Javier Castellano is very consistent of getting a high rank in each race since the win/loss ratio is the highest and he is in the third place for the win rate.","metadata":{}},{"cell_type":"code","source":"AQU = rate_jockey.loc[rate_jockey[\"track_id\"] == \"AQU\"]\nBEL = rate_jockey.loc[rate_jockey[\"track_id\"] == \"BEL\"]\nSAR = rate_jockey.loc[rate_jockey[\"track_id\"] == \"SAR\"]","metadata":{"execution":{"iopub.status.busy":"2022-11-09T08:45:28.755388Z","iopub.execute_input":"2022-11-09T08:45:28.756201Z","iopub.status.idle":"2022-11-09T08:45:28.769226Z","shell.execute_reply.started":"2022-11-09T08:45:28.756167Z","shell.execute_reply":"2022-11-09T08:45:28.768492Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"AQU10_jockey = AQU.groupby([\"jockey\"])[[\"First\",\"Second\",\"Third\",\"games\"]].sum()\nAQU10_jockey[\"win_rate\"] = AQU10_jockey[\"First\"] / AQU10_jockey[\"games\"]\nAQU10_jockey[\"win/loss_ratio\"] = (AQU10_jockey[\"First\"] + AQU10_jockey[\"Second\"]+ AQU10_jockey[\"Third\"] )/ (AQU10_jockey[\"games\"] - AQU10_jockey[\"First\"] - AQU10_jockey[\"Second\"] - AQU10_jockey[\"Third\"])\nAQU10_jockey = AQU10_jockey[AQU10_jockey[\"games\"] >= 10 ]\nAQU10_jockey[\"AQU_Rank\"] = AQU10_jockey[\"win/loss_ratio\"].rank(ascending = False)\nAQU10_jockey = AQU10_jockey.sort_values([\"win/loss_ratio\"], ascending = False)\n\nAQU10_jockey.head(10)\n","metadata":{"execution":{"iopub.status.busy":"2022-11-09T08:45:28.770271Z","iopub.execute_input":"2022-11-09T08:45:28.770742Z","iopub.status.idle":"2022-11-09T08:45:28.801839Z","shell.execute_reply.started":"2022-11-09T08:45:28.770715Z","shell.execute_reply":"2022-11-09T08:45:28.799942Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"This table shows the top 10 jockey played in Aqueduct(AQU) who has the highest 10 win/loss ratio. The reason why we sort by the ratio instead of the win rate is because the difference between top 10 win rate isn't much. However, getting into top 3 that affects the win/loss ratio seems to have a larger difference between first place and tenth place. This is a much better variable for us to consider the average performance of each jockey.","metadata":{}},{"cell_type":"code","source":"BEL10_jockey = BEL.groupby([\"jockey\"])[[\"First\",\"Second\",\"Third\",\"games\"]].sum()\nBEL10_jockey[\"win_rate\"] = BEL10_jockey[\"First\"] / BEL10_jockey[\"games\"]\nBEL10_jockey[\"win/loss_ratio\"] = (BEL10_jockey[\"First\"] + BEL10_jockey[\"Second\"]+ BEL10_jockey[\"Third\"] )/ (BEL10_jockey[\"games\"] - BEL10_jockey[\"First\"] - BEL10_jockey[\"Second\"] - BEL10_jockey[\"Third\"])\nBEL10_jockey = BEL10_jockey[BEL10_jockey[\"games\"] >= 10 ]\nBEL10_jockey[\"BEL_Rank\"] = BEL10_jockey[\"win/loss_ratio\"].rank(ascending = False)\nBEL10_jockey = BEL10_jockey.sort_values([\"win/loss_ratio\"], ascending = False)\n\nBEL10_jockey.head(10)\n","metadata":{"execution":{"iopub.status.busy":"2022-11-09T08:45:28.804353Z","iopub.execute_input":"2022-11-09T08:45:28.804677Z","iopub.status.idle":"2022-11-09T08:45:28.832294Z","shell.execute_reply.started":"2022-11-09T08:45:28.804651Z","shell.execute_reply":"2022-11-09T08:45:28.830943Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"This table shows the top 10 jockey played in Belmont(BEL) who has the highest 10 win/loss ratio.","metadata":{}},{"cell_type":"code","source":"SAR10_jockey = SAR.groupby([\"jockey\"])[[\"First\",\"Second\",\"Third\",\"games\"]].sum()\nSAR10_jockey[\"win_rate\"] = SAR10_jockey[\"First\"] / SAR10_jockey[\"games\"]\nSAR10_jockey[\"win/loss_ratio\"] = (SAR10_jockey[\"First\"] + SAR10_jockey[\"Second\"]+ SAR10_jockey[\"Third\"] )/ (SAR10_jockey[\"games\"] - SAR10_jockey[\"First\"] - SAR10_jockey[\"Second\"] - SAR10_jockey[\"Third\"])\nSAR10_jockey = SAR10_jockey[SAR10_jockey[\"games\"] >= 10 ]\nSAR10_jockey[\"SAR_Rank\"] = SAR10_jockey[\"win/loss_ratio\"].rank(ascending = False)\nSAR10_jockey = SAR10_jockey.sort_values([\"win/loss_ratio\"], ascending = False)\n\nSAR10_jockey.head(10)\n\n","metadata":{"execution":{"iopub.status.busy":"2022-11-09T08:45:28.833958Z","iopub.execute_input":"2022-11-09T08:45:28.834330Z","iopub.status.idle":"2022-11-09T08:45:28.857960Z","shell.execute_reply.started":"2022-11-09T08:45:28.834301Z","shell.execute_reply":"2022-11-09T08:45:28.856431Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"This table shows the top 10 jockey played in Saratoga(SAR) who has the highest 10 win/loss ratio.","metadata":{}},{"cell_type":"code","source":"#Create a table for radar chart\n\nradar_jockey1 = pd.merge(jockey_by_metal, AQU10_jockey,  on=[\"jockey\"], how=\"left\")\nradar_jockey1 = radar_jockey1.loc[:,[\"AQU_Rank\"]]\nradar_jockey2 = pd.merge(radar_jockey1, BEL10_jockey,  on=[\"jockey\"], how=\"left\")\nradar_jockey2 = radar_jockey2.loc[:,[\"AQU_Rank\", \"BEL_Rank\"]]\nradar_jockey3 = pd.merge(radar_jockey2, SAR10_jockey,  on=[\"jockey\"], how=\"left\")\nradar_jockey3 = radar_jockey3.loc[:,[\"AQU_Rank\", \"BEL_Rank\", \"SAR_Rank\"]]\n\nradar_jockey = radar_jockey3.head(12)\nradar_jockey = radar_jockey.reset_index()\n\n\n# ------- PART 1: Define a function that do a plot for one line of the dataset!\n\ndef make_spider( row, title, color):\n\n    # number of variable\n    categories=list(radar_jockey)[1:]\n    N = len(categories)\n\n    # What will be the angle of each axis in the plot? (we divide the plot / number of variable)\n    angles = [n / float(N) * 2 * pi for n in range(N)]\n    angles += angles[:1]\n\n    # Initialise the spider plot\n    ax = plt.subplot(4,3,row+1, polar=True, )\n\n    # If you want the first axis to be on top:\n    ax.set_theta_offset(pi / 2)\n    ax.set_theta_direction(-1)\n\n    # Draw one axe per variable + add labels labels yet\n    plt.xticks(angles[:-1], categories, color='grey', size=8)\n\n    # Draw ylabels\n    ax.set_rlabel_position(0)\n    plt.yticks([1,3,5], [\"1\",\"5\",\"10\"], color=\"grey\", size=7)\n    plt.ylim(0,10)\n\n    # Ind1\n    values=radar_jockey.loc[row].drop('jockey').values.flatten().tolist()\n    values += values[:1]\n    ax.plot(angles, values, color=color, linewidth=2, linestyle='solid')\n    ax.fill(angles, values, color=color, alpha=0.4)\n\n    # Add a title\n    plt.title(title, size=11, color=color, y=1.1)\n\n    \n# ------- PART 2: Apply the function to all individuals\n# initialize the figure\nmy_dpi=96\nplt.figure(figsize=(1000/my_dpi, 1000/my_dpi), dpi=my_dpi)\n \n# Create a color palette:\nmy_palette = plt.cm.get_cmap(\"Set2\", len(radar_jockey.index))\n \n# Loop to plot\nfor row in range(0, len(radar_jockey.index)):\n    make_spider( row=row, title= radar_jockey['jockey'][row], color=my_palette(row))","metadata":{"execution":{"iopub.status.busy":"2022-11-09T08:45:28.859585Z","iopub.execute_input":"2022-11-09T08:45:28.859943Z","iopub.status.idle":"2022-11-09T08:45:31.573632Z","shell.execute_reply.started":"2022-11-09T08:45:28.859911Z","shell.execute_reply":"2022-11-09T08:45:31.572796Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"These radar charts show the performance of the top 12 most metals received jockeys in different tracks. Smaller triangle means higher win/loss ratio ranking in different tracks. If we look at Manuel Franco, we can clearly see that he performs better in Aqueduct(AQU) than the other two tracks. Jose L. Ortiz on the other hand, performs much better in Belmont(BEL) and Saratoga(SAR) than in Aqueduct(AQU). By using this chart, we can clearly see the advantage and disadvantage for each jockey in different tracks.\n\n","metadata":{}}]}