<jupyter_start><jupyter_text>Exploratory Data Analysis of IPLThe dataset consist of data about IPL matches played from the year 2008 to 2019. IPL is a professional Twenty20 cricket league founded by the Board of Control for Cricket in India (BCCI) in 2008. The league has 8 teams representing 8 different indian cities or states. It enjoys tremendous popularity and the brand value of the IPL in 2019 was estimated to be ₹475 billion (US$6.7 billion). So let's analyse IPL through stats. Objectives:* To find the team that won the most number of matches in a season* To find the team that lost the most number of matches in a season* Does winning toss increases the chances of victory.* To find the player with most player of the match awards.* To find the city that hosted maximum number of IPL matches.* To find the most winning team for each season.* To find the on-field umpire with maximum number of IPL matches.  Downloading the DatasetThe data set used for the analysis can be found here.<jupyter_code>!pip install jovian opendatasets --upgrade --quiet<jupyter_output><empty_output><jupyter_text>Let's begin by downloading the data, and listing the files within the dataset.<jupyter_code># Change this
dataset_url = 'https://www.kaggle.com/nowke9/ipldata?select=matches.csv' 
import opendatasets as od
od.download(dataset_url)<jupyter_output>Please provide your Kaggle credentials to download this dataset. Learn more: http://bit.ly/kaggle-creds
Your Kaggle username: iambipin
Your Kaggle Key: ········<jupyter_text>The dataset has been downloaded and extracted.<jupyter_code># Change this
data_dir = './ipldata'
import os
os.listdir(data_dir)<jupyter_output><empty_output><jupyter_text>Data Preparation and CleaningLet's start by reading the csv file to Pandas DataFrame.<jupyter_code>import pandas as pd
ipl_matches_df = pd.read_csv('matches.csv')
ipl_matches_df<jupyter_output><empty_output><jupyter_text>So there are 756 rows and 18 columns. 756 rows implies that there were 756 IPL matches between 2008 and 2019.<jupyter_code>ipl_matches_df.info()
ipl_matches_df.describe()<jupyter_output><empty_output><jupyter_text>ObservationsThe following inferences can be made from the describe method:* The .csv file has data of IPL matches starting from season 2008 to 2019.* **The biggest margin of victory for the team batting first(win_by_runs) is 146 runs**.* **The biggest victory of team batting secong(win_by_wickets) is by 10 wickets**.* **75% of the victorious teams that bat first won by a margin of 19 runs**.* **75% of the victorious teams that bat second won by a margin of 6 wickets**.* There were **756 IPL matches** hosted from 2008 to 2019.<jupyter_code>ipl_matches_df.columns<jupyter_output><empty_output><jupyter_text>Let's view the unique values of each column to help us understand the dataset better.<jupyter_code>for col in ipl_matches_df:
    print(ipl_matches_df[col].unique())<jupyter_output>[    1     2     3     4     5     6     7     8     9    10    11    12
    13    14    15    16    17    18    19    20    21    22    23    24
    25    26    27    28    29    30    31    32    33    34    35    36
    37    38    39    40    41    42    43    44    45    46    47    48
    49    50    51    52    53    54    55    56    57    58    59    60
    61    62    63    64    65    66    67    68    69    70    71    72
    73    74    75    76    77    78    79    80    81    82    83    84
    85    86    87    88    89    90    91    92    93    94    95    96
    97    98    99   100   101   102   103   104   105   106   107   108
   109   110   111   112   113   114   115   116   117   118   119   120
   121   122   123   124   125   126   127   128   129   130   131   132
   133   134   135   136   137   138   139   140   141   142   143   144
   145   146   147   148   149   150   151   152   153   154   155   156
   157   158   159   160   161   162   163   164   [...]<jupyter_text>The dataset has 18 columns. Let's get acquainted with the columns.* id: The IPL match id.* season: The IPL season* city: The city where the IPL match was held.* date: The date on which the match was held.* team1: One of the teams of the IPL match* team2: The other team of the IPL match* toss_winner: The team that won the toss* toss_decision: The decision taken by the team that won the toss to 'bat' or 'field' * result: The result('normal', 'tie', 'no result') of the match.* dl_applied: (1 or 0)indicates whether Duckworth-Lewis rule was applied or not.* winner: The winner of the match.* win_by_runs: Provides the runs by which the team batting first won* win_by_runs: Provides the number of wickets by which the team batting second won.* player_of_match: The outstanding player of the match.* venue: The venue where the match was hosted.* umpire1: One of the two on-field umpires who officiate the match.* umpire2: One of the two on-field umpires who officiate the match.* umpire3: The off-field umpire who officiates the match A mere glance of the DataFrame through its columns indicate the presence of NaN values in 'umpire3' column. Let's see the count of NaN values in the column.<jupyter_code>#the first index that doesn't contain a NaN value 
ipl_matches_df.umpire3.first_valid_index()
#Confirming the first valid index
ipl_matches_df.loc[633:640]<jupyter_output><empty_output><jupyter_text>It's imperative to know the count of NaN values for each column before we proceed further.<jupyter_code>ipl_matches_df.isnull().sum()<jupyter_output><empty_output><jupyter_text>The column 'umpire3' has significant number of NaN values. As the off-field umpire parameter is insignificant, we can drop this column. The other columns that have Nan values are of type object(Pandas equivalent of Python String data type) and are very few in number(<=7).<jupyter_code>ipl_matches_df = ipl_matches_df.drop(columns=['umpire3'], axis=1)<jupyter_output><empty_output><jupyter_text>Ensure that the DataFrame is devoid of the 'umpire3' column.<jupyter_code>ipl_matches_df.head(10)<jupyter_output><empty_output><jupyter_text>Exploratory Analysis and VisualizationNow that our data set has been cleaned up, it's time to do the in-depth analysis and visualization. Let's begin by importing`matplotlib.pyplot` and `seaborn`.<jupyter_code>import seaborn as sns
import matplotlib
import matplotlib.pyplot as plt
%matplotlib inline

# sns.set_style('darkgrid')
# sns.set_style('whitegrid')
sns.color_palette("Paired")
matplotlib.rcParams['font.size'] = 14
matplotlib.rcParams['figure.figsize'] = (12, 8)
matplotlib.rcParams['figure.facecolor'] = '#00000000'<jupyter_output><empty_output><jupyter_text>The team with most number of wins per season.Each IPL season is different from its earlier one. No team other than Chennai Super Kings(in 2010 and 2011) was able to win the IPL trophy in succession. So let's analyse the team with most wins in each season.<jupyter_code>teams_per_season = ipl_matches_df.groupby('season')['winner'].value_counts()
teams_per_season
"""
for i, v in win_per_season.iteritems():
    print(i, v)
    
for items in win_per_season.iteritems():
    print(items)    
"""
year = 2008
win_per_season_df = pd.DataFrame(columns=['year', 'team', 'wins'])
for items in teams_per_season.iteritems():    
    if items[0][0]==year:
        print(items)
        win_series = pd.DataFrame({
            'year': [items[0][0]],
            'team': [items[0][1]],
            'wins': [items[1]]
        })
        win_per_season_df = win_per_season_df.append(win_series)
        year += 1   
win_per_season_df<jupyter_output><empty_output><jupyter_text>The number of wins is a discrete value. Hence, we will plot a barchart(barplot in Seaborn).<jupyter_code>sns.barplot('wins', 'team', hue='year', data=win_per_season_df, palette='Paired');<jupyter_output><empty_output><jupyter_text>From the barplot, we can easily make inferences regarding the year in which a particular team has scored the maximum wins(and also the number of wins).  Observations* **Mumbai Indians has secured most wins in four seasons(2010, 2013, 2017 and 2019).**.  The venue that hosted the maximum number of matches<jupyter_code>venue_ser = ipl_matches_df['venue'].value_counts()
venue_df = pd.DataFrame(columns=['venue', 'matches'])
for items in venue_ser.iteritems():
    temp_df = pd.DataFrame({
        'venue':[items[0]],
        'matches':[items[1]]
    })
    venue_df = venue_df.append(temp_df, ignore_index=True)
plt.title("IPL Venues")
sns.barplot(x='matches', y='venue', data=venue_df);
venue_df<jupyter_output><empty_output><jupyter_text>Observations* **<NAME> has hosted the maximum number of IPL matches followed by Wankhede Stadium and M Chinnaswamy Stadium**.* **Till 2019, IPL matches were hosted by 40 venues**.  The most successful IPL teamIn a game of sports, every team compete for victory. Hence, the team that has registered the most number of victories is the most successful team.<jupyter_code>team_wins_ser = ipl_matches_df['winner'].value_counts()

team_wins_df = pd.DataFrame(columns=["team", "wins"])
for items in team_wins_ser.iteritems():
    temp_df1 = pd.DataFrame({
        'team':[items[0]],
        'wins':[items[1]]
    })
    team_wins_df = team_wins_df.append(temp_df1, ignore_index=True)
team_wins_df
plt.title("Total Victories of IPL Teams")
sns.barplot(x='wins', y='team', data=team_wins_df, palette='Paired');<jupyter_output><empty_output><jupyter_text>Observations:* **Mumbai Indians is the most successful team(as they have won the maximum number of IPL matches -109) followed by Chennai Super Kings and Kolkata Knight Riders**.  Most Valuable PlayerWinning matters the most in a competitive league match. If a player makes the most significant contribution for his team's victory, then he's chosen as the player_of_match.The player who has won the player_of_match title on most occasions is obviously the most valuable player.<jupyter_code>mvp_ser = ipl_matches_df['player_of_match'].value_counts()

mvp_ten_df = pd.DataFrame(columns=["player", "wins"])
count = 0
for items in mvp_ser.iteritems():
    if count>9:
        break
    else:
        temp_df2 = pd.DataFrame({
            'player':[items[0]],
            'wins':[items[1]]
        })
        mvp_ten_df = mvp_ten_df.append(temp_df2, ignore_index=True)
        count += 1    
mvp_ten_df
plt.title("Top Ten IPL Players")
sns.barplot(x='wins', y='player', data=mvp_ten_df, palette='Paired');<jupyter_output><empty_output><jupyter_text>Observations:* **<NAME> is the player who won the most player of the match awards and hence is the most valuable player**.* **Six indian players have figured in the top ten IPL players list**.  Team that won the most number of toss<jupyter_code>toss_ser = ipl_matches_df['toss_winner'].value_counts()

toss_df = pd.DataFrame(columns=["team", "wins"])

for items in toss_ser.iteritems():
    temp_df3 = pd.DataFrame({
        'team':[items[0]],
        'wins':[items[1]]
    })
    toss_df = toss_df.append(temp_df3, ignore_index=True) 
toss_df<jupyter_output><empty_output><jupyter_text>**TODO** - Explore one or more columns by plotting a graph below, and add some explanation about it<jupyter_code>plt.title("How IPL Teams fared in toss?")
sns.barplot(x='wins', y='team', data=toss_df, palette='Paired');<jupyter_output><empty_output><jupyter_text>Observations:* **Mumbai Indians has won the most toss(till 2019) in IPL history**.* **All the top teams in IPL are successful in winning toss as well**. Let us save and upload our work to Jovian before continuing<jupyter_code>import jovian
jovian.commit()<jupyter_output><empty_output><jupyter_text>Asking and Answering QuestionsLet's try to find answers for the questions that will linger in an IPL fan's mind.  Q1:Does the presence of most valuable players in a team ensures IPL trophy?We have figured out the top ten players of IPL using 'Player of the Match' title as the yardstick. It is interesting to note that the top two players - <NAME> and <NAME> have never won an IPL. **Of the top ten players, 6 players(RG Sharma, <NAME>, <NAME>, <NAME>, <NAME> and <NAME>) have won the IPL**. It exemplifies the importance of the presence of most valuable player(s) in a team.<jupyter_code>mvp_ten_df<jupyter_output><empty_output><jupyter_text>Q2: Which umpire has officiated the most number of IPL matches on-field?<jupyter_code>umpire1_ser = ipl_matches_df['umpire1'].value_counts()
umpire2_ser = ipl_matches_df['umpire2'].value_counts()
umpires_df = pd.concat([umpire1_ser, umpire2_ser], axis=1)
umpires_df
umpire_ser = umpires_df.sum(axis=1)

umpire_df = pd.DataFrame(columns=["umpire", "matches"])

for items in umpire_ser.iteritems():
    temp_df4 = pd.DataFrame({
        'umpire':[items[0]],
        'matches':[items[1]]
    })
    umpire_df= umpire_df.append(temp_df4, ignore_index=True) 
umpire_df.sort_values('matches', ascending=False).head()<jupyter_output><empty_output><jupyter_text>**<NAME>(<NAME>) has officiated the most number of IPL matches on-field**, followed by former SriLankan international cricketer HDPK Dharmasena.   Q3: Which team is the most successful team in IPL?Nothing succeeds like success. In a game of cricket, winning is everything. We have narrowed down on the list of teams that made most number of wins in each season. The DataFrame win_per_season_df gives the required information. Mumbai Indians has secured most wins in four seasons(2010, 2013, 2017 and 2019).<jupyter_code>win_per_season_df<jupyter_output><empty_output><jupyter_text>Mumbai Indians secured the most number of wins(109) in IPL, followed by Chennai Super Kings.<jupyter_code>team_wins_df<jupyter_output><empty_output><jupyter_text>Of all the IPL matches played till 2019, Mumbai Indians has emerged victorious in the most number of games. They have secured most wins in four seasons. **Hence Mumbai Indians is the most successful team in IPL**.  Q4: Which city has hosted the maximum number of IPL matches?<jupyter_code>ipl_matches_df['city'].value_counts()
city_ser = ipl_matches_df['city'].value_counts()

city_df = pd.DataFrame(columns=['city', 'matches'])
for items in city_ser.iteritems():
    temp_df6 = pd.DataFrame({
        'city':[items[0]],
        'matches':[items[1]]
    })
    city_df = city_df.append(temp_df6, ignore_index=True)
plt.title("Cities that hosted IPL matches")
sns.barplot(x='matches', y='city', data=city_df);<jupyter_output><empty_output><jupyter_text>**Mumbai has hosted the maximum number of IPL matches**.  Q5: Does winning toss has any advantage?<jupyter_code>win_count = 0
for index, value in ipl_matches_df.iterrows():
    if(value['toss_winner']==value['winner']):
#         print(value['winner'])
        win_count += 1

print(f'The number of times the team winning toss have won: {win_count}')
prob = win_count/len(ipl_matches_df)
print('The probability of winning if won the toss: {:.2f}' .format(prob))<jupyter_output>The number of times the team winning toss have won: 393
The probability of winning if won the toss: 0.52<jupyter_text>**The probability of winning when the team had won the toss is 52%**. So winning toss gives a slight edge over the opponent. However it would be naive to term winning the toss as a greater advantage as there were 363 instances when the team lossing the toss has won the game. Let us save and upload our work to Jovian before continuing.<jupyter_code>import jovian
jovian.commit()<jupyter_output><empty_output><jupyter_text>Q6: What are the major victories in IPL? Is it better to defend or chase in IPL?<jupyter_code>len(ipl_matches_df)
defend_vict_ser = ipl_matches_df['win_by_runs'].value_counts()
defend_vict_ser.sort_values(ascending=True)<jupyter_output><empty_output><jupyter_text>* Of the 756 IPL matches played from 2008 to 2019, **419 matches were won chasing the target**. Hence, more victories were registered by teams chasing a total(batting second) than defending the total.* When defending a total, **the biggest victory was by 146 runs**. Let's find out that particular match.<jupyter_code>score = 146
for index, row in ipl_matches_df.iterrows():
    if(row['win_by_runs'] == score):
        print(row)<jupyter_output>id                               44
season                         2017
city                          Delhi
date                     2017-05-06
team1                Mumbai Indians
team2              Delhi Daredevils
toss_winner        Delhi Daredevils
toss_decision                 field
result                       normal
dl_applied                        0
winner               Mumbai Indians
win_by_runs                     146
win_by_wickets                    0
player_of_match         LMP Simmons
venue              Feroz Shah Kotla
umpire1                 <NAME>
umpire2                   CK Nandan
umpire3                         NaN
Name: 43, dtype: object<jupyter_text>**The greatest victory in IPL on defending a total is for Mumbai Indians when they defeated Delhi Daredevils by 146 runs on 06 May 2017 at Feroz Shah Kotla stadium, Delhi.**<jupyter_code>chasing_vict_ser = ipl_matches_df['win_by_wickets'].value_counts()
chasing_vict_ser<jupyter_output><empty_output><jupyter_text>* Of the 756 IPL matches played from 2008 to 2019, **350 matches were won defending the total**.* When chasing a target, **the biggest victory was by 10 wickets**(without losing any wickets). There were 11 such instances and we can find the details about those matches by the following code snippet:<jupyter_code>for index, row in ipl_matches_df.iterrows():
    if(row['win_by_wickets'] == 10):
        print(row)
chasing_vict_df = pd.DataFrame(columns=['victory_margin', 'instances'])

for items in chasing_vict_ser.iteritems():    
    temp_df7 = pd.DataFrame({
        'victory_margin': [items[0]],
        'instances': [items[1]]
    })
    chasing_vict_df = chasing_vict_df.append(temp_df7, ignore_index=True)
    
#to drop the first row as it represents victory margin of zero wickets(victory by defending a total)
chasing_vict_df2 = chasing_vict_df.drop([0]) 
chasing_vict_df2
plt.title('The IPL victories in numbers when chasing a total')
sns.barplot(x='victory_margin', y='instances', data=chasing_vict_df2);<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.08728454210033593, 'fraction_numerical': 0.03887879288507076, 'mean_word_length': 4.129943502824859, 'pattern_counts': {'":': 0, '<': 134, '<?xml version=': 0, '>': 134, 'https://': 1, 'lorem ipsum': 0, 'www.': 1, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 1, 'word_list_counts': {'cursed_substrings.json': 6, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '31', 'dir': 'jupyter-structured-clean-dedup', 'id': '118158', 'license': 'MIT', 'n_tokens_mistral': 6228, 'n_tokens_neox': 5622, 'n_words': 2032, 'path': 'eda_ipl_matches.ipynb', 'repo_name': 'pbipin/IPL', 'size': '18207'}