<jupyter_start><jupyter_text><jupyter_code># Import the tools you will need
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
# Install so the notebook can navigate Kaggle
!pip install kaggle
# Upload your user authentication from your local files
# The user scraped the data himself and I don't have permission to repuload it 
# on github. This is Kaggles solution.
# You have to upload your Kaggle accounts API token to source the dataset
# this link shows how https://www.youtube.com/watch?v=eEgZtNOCJhk&t=82s
# explanation starts at 1:10
# the file should read kaggle.json as default
from google.colab import files
files.upload()
# Direct the notebook to the dataset on kaggle
!mkdir -p ~/.kaggle
!cp kaggle.json ~/.kaggle/

!chmod 600 ~/.kaggle/kaggle.json
# Downloads the zip file from the kaggle website to the notebook
!kaggle datasets download -d pschale/mlb-pitch-data-20152018
# Seperate the different Excel files into CSVs
!unzip mlb-pitch-data-20152018.zip
# Take the seperated CSVs and turn them into Pandas dataframes
bats_df = pd.read_csv('atbats.csv')
games_df = pd.read_csv('games.csv')
pitches_df = pd.read_csv('pitches.csv')
players_df = pd.read_csv('player_names.csv')
# Show the head of each dataframe in order to isloate what
# columns we want in our final dataframe
players_df.head()
pitches_df.head()
games_df.head()
bats_df.head()
# From the pitches df we only want 
# type_confidence, code, type, pitch_type, and
# the ab_id. So we drop the rest
pitches_2df = pitches_df.drop(pitches_df.columns[[0, 1,2, 3,4,5,6,7,8,9,10,11,12,13,15,16,17,
                                                  18,19,20,21,22,23,24,25,26,30,31,33,34,35,36,37,38,39]], axis=1) 
# Double check
pitches_2df.head()
# From the at_bats df we only want
# ab_id, batter_id, event	g_id, pitcher_id, stand
# we drop the rest
bats_df2 = bats_df.drop(bats_df.columns[[4,5,6,7,10]], axis=1) 
# Double check
bats_df2.head()
# We want everything from the players dataframe
# No need to drop anything
# Combine the bats and pitches dataframes
new_df = pd.merge(bats_df2, pitches_2df, on='ab_id', how='outer')
# Double check
new_df
# We need to add the player names
# but the player id's are seperated into batters and pitchers
# we don't need batters so we drop that column so we can
# merge player names on pitcher_id
# g_id and event is redundant, will drop those as well
new_df2 = new_df.drop(new_df.columns[[1,2,3]], axis=1)
new_df2
# add a pitcher_id column for the merge
# drop the redundancy
players_df['pitcher_id'] = players_df['id']
players_df = players_df.drop(players_df.columns[[0]], axis=1)
# Double check
players_df.head()
# merge the dataframe
new_df3 = pd.merge(new_df2, players_df, on='pitcher_id', how='outer')
# it worked, but we have to trim the batter ids
new_df3
# We also need to drop all pitches with a type
# confidence under 2.0 to make sure which pitch was thrown
# this will also drop the batters because they only have NaN values
new_df3['Positive'] = new_df3['type_confidence']==2.000
# Double check
new_df3.head()
# create a condition so we can check the value counts
condition =  (new_df3['Positive'] == False)
condition
# check the value counts
condition.value_counts()
# create a new dataframe without the batter ids
# and without 100% certain pitch types
new_df4 = new_df3.drop( new_df3[ new_df3['Positive'] == False ].index)
# Double check
new_df4['Positive'].value_counts()
new_df4.head()
# The 'Positive' column is still there and
# we no longer need it, drop it
new_df5 = new_df4.drop(new_df4.columns[[9]], axis=1)
# Double check
new_df5.head()
# We likely won't use ab_id, drop it as well
new_df6 = new_df5.drop(new_df5.columns[[0]], axis=1)
# Double check
new_df6.head()
# this is final version of the dataframe we will use to answer our questions
# make it easy and rename it
final_df = new_df6
# Double check and make a copy
fdf = final_df
final_df.head()
# Our first question is who had the most swings and misses
# the 'code' for that is 'S'
# Create a boolean column for filtering
fdf['right_types'] = fdf['type']== 'S'
# Double check
fdf.head()
# check the value counts
fdf['right_types'].value_counts()
# drop the False columns
fdf2 = fdf.drop( fdf[ fdf['right_types'] == False ].index)
# Double check
fdf2['right_types'].value_counts()
# drop the now redundant column
fdf3 = fdf2.drop(fdf2.columns[[8]], axis=1)
# Double check
fdf3.head()
# combine the first_name and last_name columns
fdf3['name'] = fdf3['first_name']+' '+fdf3['last_name']
# double check
fdf3.head()
# delete redundant columns
fdf4 = fdf3.drop(fdf3.columns[[0, 6,7]], axis=1)
# Double check
fdf4.head()
# See which pitcher through the most whiffs
fdf4['name'].value_counts()
# import the graph set you need
import seaborn as sns
# graph the data
whiff_count  = fdf4['name'].value_counts()
whiff_count = whiff_count[:5,]
plt.figure(figsize=(10,5))
sns.barplot(whiff_count.index, whiff_count.values, alpha=0.8)
plt.title('Pitchers With the Most Whiffed Pitches')
plt.ylabel('Number of Occurrences', fontsize=12)
plt.xlabel('pitcher', fontsize=12)
plt.show()
# Quick compare to the rest of the league
whiff_count  = fdf4['name'].value_counts()
whiff_count = whiff_count[:130,]
plt.figure(figsize=(10,5))
sns.barplot(whiff_count.index, whiff_count.values, alpha=0.8)
plt.title('Whiffs per Pitcher')
plt.ylabel('Number of Occurrences', fontsize=12)
plt.xlabel('', fontsize=1)
plt.xticks()
plt.show()
# This shows us how many of each pitch type was whiffed
fdf4['pitch_type'].value_counts()
# This shows us how many of each pitch type were thrown
new_df5['pitch_type'].value_counts()
from matplotlib.pyplot import pie, axis, show
# Prepare the data for the graph
df = pd.DataFrame({
    'Pitch_Type': ['Fastball', 'Slider', 'Changeup', 'Sinker', 'Curveball', 'Knuckle/ Knuckle Curve' ],
    'Whiffs': [293290, 130949, 74456, 14470, 64291, 21875]})
# Graph the data
sums = df.Whiffs.groupby(df.Pitch_Type).sum()
plt.title('Percent of Pitches Whiffed')
axis('equal');
pie(sums, labels=sums.index);
show()
# Prepare the data for the graph
df_pitch_totals = pd.DataFrame({
    'Pitch_Type': ['Fastball', 'Slider', 'Changeup', 'Sinker', 'Curveball', 'Knuckle/ Knuckle Curve' ],
    'Whiffs': [606112, 277710, 178303, 144170, 142711, 47017]})
#Graph the data
sums = df_pitch_totals.Whiffs.groupby(df_pitch_totals.Pitch_Type).sum()
plt.title('Percent of Pitches Thrown')
axis('equal');
pie(sums, labels=sums.index);
show()
# Prepare the data for a bar graph
x_values =['Fastball', 'Slider', 'Changeup', 'Sinker', 'Curveball', 'Knuckle/ Knuckle Curve' ]
y_values = [(293290/606112)*10, (130949/277710)*10, (74456/178303)*10, (14470/144170)*10, (64291/142711)*10, (21875/47017)*10]
# Graph the data
whiff_count  = df_pitch_type_whiffs['Whiffs']
whiff_count = whiff_count[:6,]
plt.figure(figsize=(10,7))
sns.barplot( x=x_values, y=y_values, alpha=0.8)
plt.title('Percent of Total Pitches Whiffed')
plt.ylabel('Percent Whiffed', fontsize=12)
plt.xlabel('Pitch Type', fontsize=12)
plt.yticks(np.arange(0, 10, step=1))
plt.show()<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.12432814710042432, 'fraction_numerical': 0.049080622347949084, 'mean_word_length': 5.33034914950761, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 1, 'lorem ipsum': 0, 'www.': 1, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '1', 'dir': 'jupyter-structured-clean-dedup', 'id': '231240', 'license': 'MIT', 'n_tokens_mistral': 2783, 'n_tokens_neox': 2537, 'n_words': 784, 'path': 'Clean_MLB_Notebook.ipynb', 'repo_name': 'Cal-0/Cal-0-dashboard.github.io', 'size': '7070'}