<jupyter_start><jupyter_text>![Alt text](https://cdn1.img.sputniknews.com/img/105872/94/1058729488_0:339:3161:2046_1000x541_80_0_0_071f83c13cdfdf01475883e69b1089f9.jpg "Covid-19")  Explore a dataset on the modern Olympic Games, including all the Games from Athens 1896 to Rio 2016- comments: true- badges: true- catagories: [Python, Pandas, numpy]- image: images/Olympic.png The Olympic Games, which originated in ancient Greece as many as 3,000 years ago, were revived in the late 19th century and have become the world’s preeminent sporting competition. From the 8th century B.C. to the 4th century A.D., the Games were held every four years in Olympia, located in the western Peloponnese peninsula, in honor of the god Zeus. The first modern Olympics took place in 1896 in Athens, and featured 280 participants from 13 nations, competing in 43 events. Since 1994, the Summer and Winter Olympic Games have been held separately and have alternated every two years. **In this Project we have to analysis the data of olympic game by using python programing.** **Let’s Start with importing the libraries**<jupyter_code>import numpy as np
import pandas as pd
import seaborn as sns
from matplotlib import pyplot as plt<jupyter_output><empty_output><jupyter_text>Collecting information about both the data sets We are going to:1. Review the first lines of the data;2. Use the describe and info functions to collect statistical information, datatypes, column names and other information<jupyter_code>data = pd.read_csv('../input/athlete-events/athlete_events.csv')
regions = pd.read_csv('../input/athlete-events/noc_regions.csv')
data.describe()
data.info()
regions = pd.read_csv('../input/athlete-events/noc_regions.csv')
regions.head()<jupyter_output><empty_output><jupyter_text>Joining the data frames<jupyter_code>merged = pd.merge(data, regions, on='NOC', how='left')
merged.head()<jupyter_output><empty_output><jupyter_text>Distribution of the age of gold medalists Let’s start creating a new data frame including only gold medalists.<jupyter_code>goldMedals = merged[(merged.Medal == 'Gold')]
goldMedals.head()<jupyter_output><empty_output><jupyter_text>I would like to have a plot of the Age to see the distribution but I need to check first if the Age column contains NaN values.<jupyter_code>goldMedals.isnull().any()<jupyter_output><empty_output><jupyter_text>Let’s take only the values that are different from NaN.<jupyter_code>goldMedals = goldMedals[np.isfinite(goldMedals['Age'])]<jupyter_output><empty_output><jupyter_text>We can now create a countplot to see the result of our work:<jupyter_code>plt.figure(figsize=(20, 10))
plt.tight_layout()
sns.countplot(goldMedals['Age'])
plt.title('Distribution of Gold Medals')<jupyter_output><empty_output><jupyter_text>It seems that we have people with Age greater that 50 with a gold medal: Let’s know more about those people.<jupyter_code>goldMedals['ID'][goldMedals['Age'] > 50].count()<jupyter_output><empty_output><jupyter_text>65 people. Wonderul But which disciplines allows you to land a gold medal after your fifties? We will now create a new dataframe called masterDisciplines in which we will insert this new set of people and then create a visualization with it.<jupyter_code>masterDisciplines = goldMedals['Sport'][goldMedals['Age'] > 50]
plt.figure(figsize=(20, 10))
plt.tight_layout()
sns.countplot(masterDisciplines)
plt.title('Gold Medals for Athletes Over 50')<jupyter_output><empty_output><jupyter_text>It seems that our senior gold medalists are shooters, archers, sailors and, above all, horse riders! It makes sense: I cannot imagine a sprinter making 100 meters in 10 seconds at 55, but who knows!  Women in Athletics Studying the data we can try to understand how much medals we have only for women in the recent history of the Summer Games. Let’s create a filtered dataset :<jupyter_code>womenInOlympics = merged[(merged.Sex == 'F') & (merged.Season == 'Summer')]
womenInOlympics.head(10)<jupyter_output><empty_output><jupyter_text>To plot the curve over time, let’s create a plot in which we put the year (on the x-axis) and count of the number of medals per edition of the games (consider that we will have more medals for the same athlete).<jupyter_code>sns.set(style="darkgrid")
plt.figure(figsize=(20, 10))
sns.countplot(x='Year', data=womenInOlympics)
plt.title('Women medals per edition of the Games')<jupyter_output><empty_output><jupyter_text>Usually I cross-check the data: below I tried to review only the medalists for the 1900 Summer edition to see if the visualization is correct.<jupyter_code>womenInOlympics.loc[womenInOlympics['Year'] == 1900].head(10)<jupyter_output><empty_output><jupyter_text>Okay, let’s count the rows (same code as above adding the count() function and filtering only for ID)<jupyter_code>womenInOlympics['ID'].loc[womenInOlympics['Year'] == 1900].count()<jupyter_output><empty_output><jupyter_text>So we have 33 records (with repetitions, for example ‘<NAME> (-Farquhar)’ won a medal both for Tennis Women’s Singles and Tennis Mixed Doubles – To be sure I cross-checked also with Wikipedia and the outcome seems correct).  Medals per country Let’s now review the top 5 gold medal countries:<jupyter_code>goldMedals.region.value_counts().reset_index(name='Medal').head()<jupyter_output><empty_output><jupyter_text>Let’s plot this:<jupyter_code>totalGoldMedals = goldMedals.region.value_counts().reset_index(name='Medal').head(5)
g = sns.catplot(x="index", y="Medal", data=totalGoldMedals,
                height=6, kind="bar", palette="muted")
g.despine(left=True)
g.set_xlabels("Top 5 countries")
g.set_ylabels("Number of Medals")
plt.title('Medals per Country')<jupyter_output><empty_output><jupyter_text>The USA seems to be the most winning country. But which are the most awarded disciplines of American Athletes?  Disciplines with the greatest number of Gold Medals Let’s create a dataframe to filter the gold medals only for the USA.<jupyter_code>goldMedalsUSA = goldMedals.loc[goldMedals['NOC'] == 'USA']<jupyter_output><empty_output><jupyter_text>Done! Now, we can count the medals per discipline<jupyter_code>goldMedalsUSA.Event.value_counts().reset_index(name='Medal').head(20)<jupyter_output><empty_output><jupyter_text>Let’s slice the dataframe using only the data of male athletes to better review it:<jupyter_code>basketballGoldUSA = goldMedalsUSA.loc[(goldMedalsUSA['Sport'] == 'Basketball') & (goldMedalsUSA['Sex'] == 'M')].sort_values(['Year'])
basketballGoldUSA.head(15)<jupyter_output><empty_output><jupyter_text>What we supposed is true: the medals are not grouped by Edition/Team but we were counting the gold medals of each member of the team! Let’s proceed grouping by year the athletes – the idea is to create a new dataframe to make a pre-filter using only the first record for each member of the team.<jupyter_code>groupedBasketUSA = basketballGoldUSA.groupby(['Year']).first()
groupedBasketUSA
groupedBasketUSA['ID'].count()<jupyter_output><empty_output><jupyter_text>What is the median height/weight of an Olympic medalist? Let’s try to plot a scatterplot of height vs weight to see the distribution of values (without grouping by discipline). First of all, we have to take again the goldMedals dataframe<jupyter_code>goldMedals.head()<jupyter_output><empty_output><jupyter_text>We can see that we have NaN values both in height and weight columns At this point, we can act as follows:1. Using only the rows that has a value in the Height and Weight columns;1. Replace the value with the mean of the column. Solution 2 in my opinion it is not the best way to go: we are talking about data of athletes of different ages and different disciplines (that have done different training). Let’s go with solution 1. The first thing to do is to collect general information about the dataframe that we have to use: goldMedals.<jupyter_code>goldMedals.info()<jupyter_output><empty_output><jupyter_text>Okay, we have more than 13.000 rows. We will now create a dataframe filtering only the rows that has the column Height and Weight populated.<jupyter_code>notNullMedals = goldMedals[(goldMedals['Height'].notnull()) & (goldMedals['Weight'].notnull())]
plt.figure(figsize=(12, 10))
ax = sns.scatterplot(x="Height", y="Weight", data=notNullMedals)
plt.title('Height vs Weight of Olympic Medalists')<jupyter_output><empty_output><jupyter_text>The vast majority of the samples show a linear relation between height and weight (the more the weight, the more the height). We have exceptions and I am willing to know more! For example, let’s see which is the athlete that weighs more than 160 kilograms.<jupyter_code>notNullMedals.loc[notNullMedals['Weight'] > 160]
MenOverTime = merged[(merged.Sex == 'M') & (merged.Season == 'Summer')]
WomenOverTime = merged[(merged.Sex == 'F') & (merged.Season == 'Summer')]
MenOverTime.head()
part = MenOverTime.groupby('Year')['Sex'].value_counts()
plt.figure(figsize=(20, 10))
part.loc[:,'M'].plot()
plt.title('Variation of Male Athletes over time')
part = WomenOverTime.groupby('Year')['Sex'].value_counts()
plt.figure(figsize=(20, 10))
part.loc[:,'F'].plot()
plt.title('Variation of Female Athletes over time')<jupyter_output><empty_output><jupyter_text>What I immediately saw is that for women:1. We have a steep increase in the population;1. The grow is constant. On the other hand, the grow for men seems less strong:1. After the 1990 we can see a relevant decrease in the number of male athletes at the summer games;1. The growth has slowly restarted recently.<jupyter_code>plt.figure(figsize=(20, 10))
sns.boxplot('Year', 'Age', data=MenOverTime)
plt.title('Variation of Age for Male Athletes over time')<jupyter_output><empty_output><jupyter_text>What is strange for me is the age of some athletes in the games between the 1924 and the 1948: let’s check all the people with age greater than 80.<jupyter_code>MenOverTime.loc[MenOverTime['Age'] > 80].head(10)
plt.figure(figsize=(20, 10))
sns.boxplot('Year', 'Age', data=WomenOverTime)
plt.title('Variation of Age for Female Athletes over time')<jupyter_output><empty_output><jupyter_text>Interesting points for me:* Generally, the age distribution starts has a lower minimum and a lower maximum;* In 1904 the age distribution is strongly different from the other Olympics: let’s know more about this point:<jupyter_code>WomenOverTime.loc[WomenOverTime['Year'] == 1904]<jupyter_output><empty_output><jupyter_text>We will now try using a pointplot to visualize the variation in weight over athletes. The first graph will show data for men, the second for women:<jupyter_code>plt.figure(figsize=(20, 10))
sns.pointplot('Year', 'Weight', data=MenOverTime)
plt.title('Variation of Weight for Male Athletes over time')
plt.figure(figsize=(20, 10))
sns.pointplot('Year', 'Weight', data=WomenOverTime)
plt.title('Variation of Weight for Female Athletes over time')<jupyter_output><empty_output><jupyter_text>What we can see is that it seems that we do not have data for women before 1924. Let’s try filtering all the women athletes for that period to review this point:<jupyter_code>womenInOlympics.loc[womenInOlympics['Year'] < 1924].head(20)<jupyter_output><empty_output><jupyter_text>Using the same pointplot (with a different palette) we can plot the weight change along time. The first graph will show the information for men, the second for women:<jupyter_code>womenInOlympics.loc[womenInOlympics['Year'] < 1924].head(20)
plt.figure(figsize=(20, 10))
sns.pointplot('Year', 'Height', data=WomenOverTime, palette='Set2')
plt.title('Variation of Height for Female Athletes over time')<jupyter_output><empty_output><jupyter_text>What we may see:* For both men and women, the height is incrementing over time but it is decreasing between the 2012 and the 2016.* For women we have a peak between 1928 and 1948, let’s deepen this point:<jupyter_code>WomenOverTime.loc[(WomenOverTime['Year'] > 1924) & (WomenOverTime['Year'] < 1952)].head(10)
MenOverTime.head()
itMenOverTime = MenOverTime.loc[MenOverTime['region'] == 'Italy']
sns.set(style="darkgrid")
plt.figure(figsize=(20, 10))
sns.countplot(x='Year', data=itMenOverTime, palette='Set2')
plt.title('Variation of Age for Italian Male Athletes over time')<jupyter_output><empty_output><jupyter_text>now we can plot the change over time:<jupyter_code>itWomenOverTime = WomenOverTime.loc[WomenOverTime['region'] == 'Italy']
sns.set(style="darkgrid")
plt.figure(figsize=(20, 10))
sns.countplot(x='Year', data=itWomenOverTime, palette='Set2')
plt.title('Variation of Age for Italian Female Athletes over time')<jupyter_output><empty_output><jupyter_text>Let’s first of all isolate all the discipline of the Olympics dataframe. My idea is to see if Gymnastics is called differently or if there is any type.<jupyter_code>MenOverTime['Sport'].unique().tolist()<jupyter_output><empty_output><jupyter_text>Okay, the string to use to filter is ‘Gymnastics’: let’s create two new dataframes for men and women.<jupyter_code>gymMenOverTime = MenOverTime.loc[MenOverTime['Sport'] == 'Gymnastics']
gymWomenOverTime = WomenOverTime.loc[WomenOverTime['Sport'] == 'Gymnastics']<jupyter_output><empty_output><jupyter_text>Okay: let’s now create our plot for male and female athletes and then we can make our observations<jupyter_code>plt.figure(figsize=(20, 10))
sns.barplot('Year', 'Weight', data=gymMenOverTime)
plt.title('Weight over year for Male Gymnasts')<jupyter_output><empty_output><jupyter_text>A few things I noticed:1. The weight for female Gymnasts has go down for 60 to 50 kilograms on average;1. The weight for men has been more or less stable since 1964;1. The height is more stable for both men and women. Also, men weight data from 1924 seems missing: let’s check.<jupyter_code>plt.figure(figsize=(20, 10))
sns.barplot('Year', 'Height', data=gymMenOverTime)
plt.title('Height over year for Male Gymnasts')
plt.figure(figsize=(20, 10))
sns.barplot('Year', 'Weight', data=gymWomenOverTime)
plt.title('Weight over year for Female Gymnasts')
plt.figure(figsize=(20, 10))
sns.barplot('Year', 'Height', data=gymWomenOverTime)
plt.title('Height over year for Female Gymnasts')
gymMenOverTime['Weight'].loc[gymMenOverTime['Year'] == 1924].isnull().all()<jupyter_output><empty_output><jupyter_text>Weightlifting Let’s work on an analysis similar to what we have done for Gymnastics also for the Lifters. We can start creating a new, dedicated dataframe<jupyter_code>wlMenOverTime = MenOverTime.loc[MenOverTime['Sport'] == 'Weightlifting']
wlWomenOverTime = WomenOverTime.loc[WomenOverTime['Sport'] == 'Weightlifting']<jupyter_output><empty_output><jupyter_text>Okay: let’s now create our plot for male and female athletes and then we can make our observations<jupyter_code>plt.figure(figsize=(20, 10))
sns.pointplot('Year', 'Weight', data=wlMenOverTime, palette='Set2')
plt.title('Weight over year for Male Lifters')
plt.figure(figsize=(20, 10))
sns.pointplot('Year', 'Height', data=wlMenOverTime, palette='Set2')
plt.title('Height over year for Male Lifters')
plt.figure(figsize=(20, 10))
sns.pointplot('Year', 'Weight', data=wlWomenOverTime)
plt.title('Weight over year for Female Lifters')
plt.figure(figsize=(20, 10))
sns.pointplot('Year', 'Height', data=wlWomenOverTime)
plt.title('Height over year for Female Lifters')<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.10580628306446346, 'fraction_numerical': 0.022010319378224806, 'mean_word_length': 6.97084851639771, 'pattern_counts': {'":': 0, '<': 153, '<?xml version=': 0, '>': 155, 'https://': 1, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '37', 'dir': 'jupyter-structured-clean-dedup', 'id': '637985', 'license': 'Apache-2.0', 'n_tokens_mistral': 5167, 'n_tokens_neox': 4683, 'n_words': 1592, 'path': '_notebooks/2021-07-25-olympic_games_analysis_using_python.ipynb', 'repo_name': 'sakibb019/Portfolio', 'size': '15317'}