Statistical Analysis with Python: Pierre-Emerick Aubameyang
Editor — Ishmael Njie
Following Henrikh Mkhitaryan’s arrival at Arsenal, we (Arsenal fans) were convinced that he had ‘let slip’ of the imminent arrival of former team-mate, Pierre-Emerick Aubameyang. The pair were a lethal combination during their time together at Borussia Dortmund; Arsenal fans were excited at the prospect of the pair playing together once again.
Pierre-Emerick Aubameyang signed for Arsenal for a club record fee on Transfer Deadline Day (31st January). Winning last season’s Bundesliga top goal scorer award with 31 goals, he is touted as one of the best strikers in the world.
So as an excited Arsenal fan, I decided to do some analysis to find out how good Aubameyang really is (and to practice more Python).
ESPN provides great statistics of each player divided by year. I selected data dating back to 2012, during his time at French side Saint-Etienne. Bringing these statistics into Excel made it easier to read into Python.
To start off, we need to import the relevant libraries that will help us to clean and analyse the data.
import pandas as pd
import seaborn as sb
import matplotlib.pyplot as plt
Next, we will read each csv file for each year as a Dataframe (DF).
df1 = pd.read_csv(‘Aubameyang2012.csv’,encoding = “ISO-8859–1”)
df2 = pd.read_csv(‘Aubameyang2013.csv’,encoding = “ISO-8859–1”)
df3 = pd.read_csv(‘Aubameyang2014.csv’,encoding = “ISO-8859–1”)
df4 = pd.read_csv(‘Aubameyang2015.csv’,encoding = “ISO-8859–1”)
df5 = pd.read_csv(‘Aubameyang2016.csv’,encoding = “ISO-8859–1”)
df6 = pd.read_csv(‘Aubameyang2017.csv’,encoding = “ISO-8859–1”)
All of the data in different dataframes is no good to us, so next we will have to bring together all of the dataframes using the ‘concat’ method. Following this, I noticed that the date format had to be changed so that it was easy to sort correctly. We will then create a new DF with the new columns and column names.
PEA = pd.concat([df1, df2, df3, df4, df5, df6]) date = pd.to_datetime(PEA['Date'], dayfirst = True)
PEA['NewDate'] = dateAuba = PEA[['Team', 'Oppo','NewDate', 'Comp', 'Res', 'Appear', 'g', 'a', 'sh','sg', 'fc', 'fs', 'yc', 'rc']]
Auba.columns = ['Team', 'Opponent','Date', 'Competition', 'Result', 'Appearance', 'Goals', 'Assists', 'Shots','Shots on Goal', 'Fouls Committed', 'Fouls Suffered', 'Yellow Cards', 'Red Cards']
Here, we will sort the DF via date
PEA2 = Auba.sort_values(‘Date’, ascending = True)
What we will do next is save the DF as a csv file, this will help to reassign the index of each of the observations. As you can see in the previous image, the first instance has an index of 38. The indices have not changed after the ‘concat’ method.
PEA2.to_csv(‘Pierre1.csv’)
PEA3 = pd.read_csv(‘Pierre1.csv’)
After reading the csv back into Python, we can see that the first labelled column is the index values from previous. We can create a DF that drops this column as it is no use to us.
PEA4 = PEA3.drop(columns = [‘Unnamed: 0’])
During data collection, one has to be mindful of null/NaN values in the dataset. Let us check for any missing values.
Null = PEA4.isnull().any(axis=0)
Indicated by the ‘True’ value, there are columns with null values, so we have to investigate this. We will create a DF with all of the rows that contain NaN values.
NAN = PEA4[PEA4.isnull().any(axis=1)]
Through investigation, I found that the first instance needs to be amended. In actual fact, Aubameyang won that game to win the Coupe de la Ligue Final against Stade Rennais during his time at Saint-Etienne.
PEA4.iat[85,0] = ‘St Etienne’
PEA4.iat[85,1] = ‘H — Rennes’
PEA4.iat[85,4] = ‘W 1–0’
Onto the next instances, under Appearance, you can see that they are all noted as ‘Unused Substitute’. Being an Unused Sub, this implies that Pierre did not play. So for our analysis, it is irrelevant to us.
PEA5 = PEA4.loc[PEA4[‘Appearance’].str.contains(‘Unused Substitute’)==False]
One thing I had noticed is that there was an instance at the last row of the DF that was not within our time frame.
PEA5.tail()
The last instance, his match against Morocco is outside our time frame, this is in the 2017/2018 season and we are only looking at 2011/12 to 2016/17. So we will proceed to drop that row.
last_row = len(PEA5) — 1
PEA6 = PEA5.drop(PEA5.index[last_row])
Again, we will save the new clean data as a csv file and read it back in (This is not a key aspect in analysis, this is just for me).
PEA6.to_csv(‘PEA_Stats.csv’)
PEA7 = pd.read_csv(‘PEA_Stats.csv’)
PEA8 = PEA7.drop(columns = [‘Unnamed: 0’])
All of the above was just cleaning the data; in my opinion, this is the most important aspect in data analysis is the preparation and cleaning of data. This is to ensure accurate results and easier data handling.
Next, we will look into the summary statistics of the data.
Summary = PEA8.describe()
Count: The count illustrates the number of instances in the dataset. So from this, we can say that during this time frame, he made 284 appearances.
Mean: a measure of centrality. So looking at the mean of the ‘Goals’ column, we can see that Pierre scores just over 0.5 goals a game. Meaning, roughly he scores a goal every 2 games. We can also see that he is not really known for his assists, assisting on average, just over 15% of the time.
Std: Standard Deviation, measure of variance.
Percentiles: 25%, 50%, 75% being the first, second (median) and third quartile respectively.
Min,Max: Smallest and largest value respectively.
We can look at more statistics to have a greater understanding of his performance.
Instead of performing this summary with many rows and columns, we can narrow down our stat search. We can compute the ratio of goals to appearances. This should result in the same value as the mean of goals.
def Appear_ratio():
Appear = PEA8[‘Team’].count()
Goals = PEA8[‘Goals’].sum()
ratio = Goals/Appear
print(‘Total Appearances: ‘ +str(Appear))
print(‘Total Goals: ‘ +str(Goals))
print(‘Goals to Appearance ratio: ‘ +str(ratio))
return
We can also look at the efficiency of Aubameyang based on his Shots compared to his goals.
def ShotConversion():
Goals = PEA8['Goals'].sum()
Shots = PEA8['Shots'].sum()
Convert = Goals/Shots
print('Total goals: ' +str(Goals))
print('Total shots: ' +str(Shots))
print('Shot conversion rate: ' +str(Convert))
return
This tells us that if Pierre takes a shot, he is likely to score 19% of the time. However, if we look at the shots on target compared to goals, this increases to around 40%.
Let us look at graphs to visualise the data.
First, let’s look at the most important thing for a striker to deliver: Goals. I created new columns to separate both the month of the matches and the ground on which they were played on, whether they were home or away.
Ground = []
for i in PEA8[‘Opponent’]:
Ground.append(i[0])
PEA8[‘Ground’] = GroundMonth = []
for i in PEA8[‘Date’]:
Month.append(i[5:7])
PEA8[‘Month’] = Month
Now, Let us look at how well Aubameyang performs each month based on his goal tally.
def plotGoal_Month():
Aug = PEA8.loc[PEA8['Month'] == '08', 'Goals'].sum()
Sep = PEA8.loc[PEA8['Month'] == '09', 'Goals'].sum()
Oct = PEA8.loc[PEA8['Month'] == '10', 'Goals'].sum()
Nov = PEA8.loc[PEA8['Month'] == '11', 'Goals'].sum()
Dec = PEA8.loc[PEA8['Month'] == '12', 'Goals'].sum()
Jan = PEA8.loc[PEA8['Month'] == '01', 'Goals'].sum()
Feb = PEA8.loc[PEA8['Month'] == '02', 'Goals'].sum()
Mar = PEA8.loc[PEA8['Month'] == '03', 'Goals'].sum()
Apr = PEA8.loc[PEA8['Month'] == '04', 'Goals'].sum()
May = PEA8.loc[PEA8['Month'] == '05', 'Goals'].sum()
Jun = PEA8.loc[PEA8['Month'] == '06', 'Goals'].sum()
Jul = PEA8.loc[PEA8['Month'] == '07', 'Goals'].sum()
GoalM = [Aug,Sep,Oct,Nov,Dec,Jan,Feb,Mar,Apr,May,Jun,Jul]
x = ['Aug','Sep','Oct','Nov','Dec','Jan','Feb','Mar','Apr','May','Jun','Jul'] sb.set()
dims = (11.7,8.27) #A4 dimensions
fig, ax = plt.subplots(figsize=dims) BarG = sb.barplot(x=x, y=GoalM, ax=ax)
BarG.set_xticklabels(BarG.get_xticklabels(), fontsize = 14) plt.xlabel('Month',fontsize = 18)
plt.ylabel('Freq of Goals',fontsize = 18)
BarG.set_title('Distribution of Monthly Goals', fontsize = 20)
FigBar = BarG.get_figure()
FigBar.savefig('BarPlot_MGoals.png')
Now looking at the graph, we can see that he is most prolific in the month of February, which is fitting as he scored on his debut for Arsenal on the 3rd February 2018. Following that, September seems to be a prolific month for him, implying that he starts the season fairly well. One can say it is expected that June and July are not prolific months for Pierre as they are considered as the off season due to most European club competitions ending in May.
In addition, we can look at his performance at Home and Away.
From this graph, we can conclude that Pierre scores most of his goals playing at his Home ground. However, the measures do not seem to be far from one another. If we take the sum of the goals at both home and away, we can have a clearer understanding.
HOME = PEA8.loc[PEA8[‘Ground’]==’H’]
AWAY = PEA8.loc[PEA8[‘Ground’]==’A’]print(HOME[‘Goals’].sum())
print(AWAY[‘Goals’].sum())
The sums for home and away were 84 and 80 goals respectively. So he has only scored 4 more goals at the home ground of his club than away at an opponent, which could either imply that he performs better at home, but also does not shy away from the goals at the opposition’s ground.
To conclude, Arsenal fans are excited with the arrival of the prolific striker following the exit of ‘mercenary’ Alexis Sanchez. His goals to game ratio of 0.57 is very impressive and Arsenal fans have been screaming for a lethal centre forward to mimic the days of Thierry Henry. His debut goal and immediate involvement is likely to foreshadow a colourful future for Aubameyang and the Gunners. If I had one message for Arsene Wenger, it would be to play him in February!!
Thank you for reading!