#!/usr/bin/env python
# coding: utf-8
#
# In[3]:
get_ipython().run_line_magic('load_ext', 'watermark')
get_ipython().run_line_magic('watermark', '-a "Romell D.Z." -u -d -p pandas,numpy,seaborn,matplotlib')
# # Peru road to Russia World Cup 2018
# ![world-cup-18](https://github.com/romellfudi/ExploratoryDataAnalysis/blob/master/snapshot/fifa_world_cup_2018.jpg?raw=1)
# In[ ]:
# Cargamos las librerías
import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
# Formateamos una vista legible
get_ipython().run_line_magic('matplotlib', 'inline')
get_ipython().run_line_magic('config', "InlineBackend.figure_format = 'retina'")
# # Preprocessing FIFA DATA
# ## Load Data from [SOFIFA]
#
# [SOFIFA]:
# In[ ]:
# Data públicada en Enero en Kaggle
FIFA18 = pd.read_csv('CompleteDataset.csv', low_memory=False)
FIFA18.columns
# Indicamos los features a trabajar, dejando a un lado el resto
# In[ ]:
interesting_columns = [
'Name',
'Age',
'Nationality',
'Overall',
'Potential',
'Club',
'Value',
'Wage',
'Preferred Positions'
]
FIFA18 = pd.DataFrame(FIFA18, columns=interesting_columns)
# ## Summarize Data
# In[ ]:
get_ipython().run_line_magic('load_ext', 'google.colab.data_table')
# Vista de la data
FIFA18.head()
# In[ ]:
# Descripción de los features
FIFA18.info()
# ## Preprocess Data
# Cambiamos los vaores de "Value" & "Wage", extrayendo los miles y millones, tienendo los valores numéricos. Los cuales son almacenados en nuevos features 'ValueNum' y 'WageNum'.
# In[ ]:
# Supporting function for converting string values into numbers
def str2number(amount):
if amount[-1] == 'M':
return float(amount[1:-1])*1000000
elif amount[-1] == 'K':
return float(amount[1:-1])*1000
else:
return float(amount[1:])
FIFA18['ValueNum'] = FIFA18['Value'].apply(lambda x: str2number(x))
FIFA18['WageNum'] = FIFA18['Wage'].apply(lambda x: str2number(x))
# Sintetizamos el feature 'Preferred Positions' extrayendo únicamente el primer cáracter, omitiendo así la doble posición del jugador
# In[ ]:
FIFA18['Position'] = FIFA18['Preferred Positions'].str.split().str[0]
# Seleccionamos el Grupo donde se encuentra nuestro Perú, Grupo C : \['Francia','Dinamarca','Perú','Australia'\].
# In[ ]:
GroupC = FIFA18[FIFA18.Nationality.isin(['France','Denmark','Peru','Australia'])]
# Extraemos las medias de los salarios por nacionalidad para el GrupoC
# In[ ]:
GroupC_Average = FIFA18.groupby('Nationality').agg({'ValueNum':np.mean,'WageNum':np.mean})
GroupC_Average = GroupC_Average.reindex(['France','Denmark','Peru','Australia'])
GroupC_Average
# # Data Visualization
# ## Age
# Visualizamos las edades por un histograma.
# In[ ]:
plt.figure(figsize=(16,8))
sns.set_style("whitegrid")
plt.title('Grouping players by Age', fontsize=30, fontweight='bold', y=1.05,)
plt.xlabel('Number of players', fontsize=25)
plt.ylabel('Players Age', fontsize=25)
sns.countplot(x="Age", data=FIFA18, palette="hls");
plt.show()
# ## Monto Acomulado (Miles de €)
# In[ ]:
plt.figure(figsize=(16,8))
sns.set_style("whitegrid")
plt.title('Grouping players by Overall', fontsize=30, fontweight='bold', y=1.05,)
plt.xlabel('Number of players', fontsize=25)
plt.ylabel('Players Age', fontsize=25)
sns.countplot(x="Overall", data=FIFA18, palette="hls");
plt.show()
# ## Preferred Position
# In[ ]:
plt.figure(figsize=(16,8))
sns.set_style("whitegrid")
plt.title('Grouping players by Preferred Position', fontsize=30, fontweight='bold', y=1.05,)
plt.xlabel('Number of players', fontsize=25)
plt.ylabel('Players Age', fontsize=25)
sns.countplot(x="Position", data=FIFA18, palette="hls");
plt.show()
# ## Nationality
# In[ ]:
FIFA18["Nationality"].value_counts().head(25)
# Podemos destacar que una gran cantidad se centraliza en Europa, especialmente en Inglaterra, Alemania, España y Francia
# ## Value
# Buscamos y listamos a los 20 jugadores que más cobran Netamente
# In[ ]:
sorted_players = FIFA18.sort_values(["ValueNum"], ascending=False).head(20)
sorted_players[["Name" ,"Age" ,"Nationality" ,"Club" ,"Position" ,"Value"]].reset_index(drop=True)
# Realizamos una vista de disperción de la valoración del jugador por sus edades e ingresos:
# In[ ]:
plt.figure(figsize=(16,8))
sns.set_style("whitegrid")
plt.title('Players Value according to their Age and Overall', fontsize=30, fontweight='bold', y=1.05,)
plt.xlabel('Age', fontsize=25)
plt.ylabel('Overall', fontsize=25)
age = FIFA18["Age"].values
overall = FIFA18["Overall"].values
value = FIFA18["ValueNum"].values
# Subdividimos los millones para tener una vista legible mediante el área de la ganancia
plt.scatter(age, overall, s = value/100000, edgecolors='black')
plt.show()
# ### 2.6 Wage
# Listamos a los 20 jugadores con más recaudación.
# In[ ]:
sorted_players = FIFA18.sort_values(["WageNum"], ascending=False).head(20)
sorted_players[["Name" ,"Age" ,"Nationality" ,"Club" ,"Position" ,"Wage"]].reset_index(drop=True)
# Realizamos una vista de disperción de ingresos del jugador por sus edades y Valoración:
# In[ ]:
plt.figure(figsize=(16,8))
sns.set_style("whitegrid")
plt.title('Players Wage according to their Age and Overall', fontsize=30, fontweight='bold', y=1.05,)
plt.xlabel('Age', fontsize=25)
plt.ylabel('Overall', fontsize=25)
age = FIFA18["Age"].values
overall = FIFA18["Overall"].values
value = FIFA18["WageNum"].values
plt.scatter(age, overall, s = value/500, edgecolors='black', color="red")
plt.show()
# ## 3 - Best Squad Analysis
# Seleccionamos una vista más simplee de los jugadores: Nombre, Edad, Nacionalidad, Valoración, Potencial, Club al que actualmente pertenece(puede estar en blanco),Posición, Recaudación, y Salario.
# In[ ]:
FIFA18 = FIFA18[['Name', 'Age', 'Nationality', 'Overall', 'Potential', 'Club', 'Position', 'Value', 'Wage']]
FIFA18.head(10)
# ### 3.1 Squad of Highest Overall Players
# Cúal es la mejor formación deacuerdo a base de hechos de la FIFA?
# In[ ]:
def get_best_squad(formation):
FIFA18_copy = FIFA18.copy()
store = []
for i in formation:
store.append([
i,
FIFA18_copy.loc[[FIFA18_copy[FIFA18_copy['Position'] == i]['Overall'].idxmax()]]['Name'].to_string(index = False),
FIFA18_copy[FIFA18_copy['Position'] == i]['Overall'].max(),
FIFA18_copy.loc[[FIFA18_copy[FIFA18_copy['Position'] == i]['Overall'].idxmax()]]['Age'].to_string(index = False),
FIFA18_copy.loc[[FIFA18_copy[FIFA18_copy['Position'] == i]['Overall'].idxmax()]]['Club'].to_string(index = False),
FIFA18_copy.loc[[FIFA18_copy[FIFA18_copy['Position'] == i]['Overall'].idxmax()]]['Value'].to_string(index = False),
FIFA18_copy.loc[[FIFA18_copy[FIFA18_copy['Position'] == i]['Overall'].idxmax()]]['Wage'].to_string(index = False)
])
FIFA18_copy.drop(FIFA18_copy[FIFA18_copy['Position'] == i]['Overall'].idxmax(),
inplace = True)
return pd.DataFrame(np.array(store).reshape(11,7),
columns = ['Position', 'Player', 'Overall', 'Age', 'Club', 'Value', 'Wage'])
# In[ ]:
# 4-3-3
squad_433 = ['GK', 'RB', 'CB', 'CB', 'LB', 'CDM', 'CM', 'CAM', 'RW', 'ST', 'LW']
print ('4-3-3')
get_best_squad(squad_433))
# In[ ]:
# 4-4-2
squad_442 = ['GK', 'RB', 'CB', 'CB', 'LB', 'RM', 'CM', 'CM', 'LM', 'ST', 'ST']
print ('4-4-2')
get_best_squad(squad_442)
# In[ ]:
# 4-2-3-1
squad_4231 = ['GK', 'RB', 'CB', 'CB', 'LB', 'CDM', 'CDM', 'CAM', 'CAM', 'CAM', 'ST']
print ('4-2-3-1')
get_best_squad(squad_4231)
# Ahora, veamos diferentes posiciones para distintos features.
# In[ ]:
def get_best_squad_n(formation, nationality, measurement = 'Overall'):
FIFA18_copy = FIFA18.copy()
FIFA18_copy = FIFA18_copy[FIFA18_copy['Nationality'] == nationality]
store = []
for i in formation:
store.append([
FIFA18_copy.loc[[FIFA18_copy[FIFA18_copy['Position'].str.contains(i)][measurement].idxmax()]]['Position'].to_string(index = False),
FIFA18_copy.loc[[FIFA18_copy[FIFA18_copy['Position'].str.contains(i)][measurement].idxmax()]]['Name'].to_string(index = False),
FIFA18_copy[FIFA18_copy['Position'].str.contains(i)][measurement].max(),
FIFA18_copy.loc[[FIFA18_copy[FIFA18_copy['Position'].str.contains(i)][measurement].idxmax()]]['Age'].to_string(index = False),
FIFA18_copy.loc[[FIFA18_copy[FIFA18_copy['Position'].str.contains(i)][measurement].idxmax()]]['Club'].to_string(index = False),
FIFA18_copy.loc[[FIFA18_copy[FIFA18_copy['Position'].str.contains(i)][measurement].idxmax()]]['Value'].to_string(index = False),
FIFA18_copy.loc[[FIFA18_copy[FIFA18_copy['Position'].str.contains(i)][measurement].idxmax()]]['Wage'].to_string(index = False)
])
FIFA18_copy.drop(FIFA18_copy[FIFA18_copy['Position'].str.contains(i)][measurement].idxmax(),
inplace = True)
return np.mean([x[2] for x in store]).round(2), pd.DataFrame(np.array(store).reshape(11,7),
columns = ['Position', 'Player', measurement, 'Age', 'Club', 'Value', 'Wage'])
# In[ ]:
def get_summary_n(squad_list, squad_name, nationality_list):
summary = []
for i in nationality_list:
count = 0
for j in squad_list:
# for overall rating
O_temp_rating, _ = get_best_squad_n(formation = j, nationality = i, measurement = 'Overall')
# for potential rating & corresponding value
P_temp_rating, _ = get_best_squad_n(formation = j, nationality = i, measurement = 'Potential')
summary.append([i, squad_name[count], O_temp_rating.round(2), P_temp_rating.round(2)])
count += 1
return summary
# Para cada formación indicamos la mejor estratégia, sin violar las reglas fundamentales del juego. Ejm: 1 portero, etc,etc.
# In[ ]:
squad_343_strict = ['GK', 'CB', 'CB', 'CB', 'RB|RWB', 'CM|CDM', 'CM|CDM', 'LB|LWB', 'RM|RW', 'ST|CF', 'LM|LW']
squad_442_strict = ['GK', 'RB|RWB', 'CB', 'CB', 'LB|LWB', 'RM', 'CM|CDM', 'CM|CAM', 'LM', 'ST|CF', 'ST|CF']
squad_4312_strict = ['GK', 'RB|RWB', 'CB', 'CB', 'LB|LWB', 'CM|CDM', 'CM|CAM|CDM', 'CM|CAM|CDM', 'CAM|CF', 'ST|CF', 'ST|CF']
squad_433_strict = ['GK', 'RB|RWB', 'CB', 'CB', 'LB|LWB', 'CM|CDM', 'CM|CAM|CDM', 'CM|CAM|CDM', 'RM|RW', 'ST|CF', 'LM|LW']
squad_4231_strict = ['GK', 'RB|RWB', 'CB', 'CB', 'LB|LWB', 'CM|CDM', 'CM|CDM', 'RM|RW', 'CAM', 'LM|LW', 'ST|CF']
# In[ ]:
squad_list = [squad_343_strict, squad_442_strict, squad_4312_strict, squad_433_strict, squad_4231_strict]
squad_name = ['3-4-3', '4-4-2', '4-3-1-2', '4-3-3', '4-2-3-1']
# # 3 Group C
# ## 3.1 France
#
# Extramos diferentes posiciónes que pueden generarse para Francia, juntamente con el promedio que generan y sus ratings.
# In[ ]:
France = pd.DataFrame(np.array(get_summary_n(squad_list, squad_name, ['France'])).reshape(-1,4),
columns = ['Nationality', 'Squad', 'Overall', 'Potential'])
France.set_index('Nationality', inplace = True)
France[['Overall', 'Potential']] = France[['Overall', 'Potential']].astype(float)
France
# Veamos, la mejor estratégia para Francia sería usar 4-3-3; mientra que las estratégias 4-4-2, and 4-2-3-1 son las que le siguen en dicho orden. Los mejores 11 con una estratégia 4-3-3 brinda actualmente sus mejores partidos hasta la fecha, pero mientras una alineación 4-4-2 le brinda mayor potencial máximo.
# In[ ]:
rating_433_FR_Overall, best_list_433_FR_Overall = get_best_squad_n(squad_433_strict, 'France', 'Overall')
print('-Overall-')
print('Average rating: {:.1f}'.format(rating_433_FR_Overall))
best_list_433_FR_Overall
# In[ ]:
rating_442_FR_Potential, best_list_442_FR_Potential = get_best_squad_n(squad_442_strict, 'France', 'Potential')
print('-Potential-')
print('Average rating: {:.1f}'.format(rating_442_FR_Potential))
best_list_442_FR_Potential
# ![griezmann](https://github.com/romellfudi/ExploratoryDataAnalysis/blob/master/snapshot/griezmann.jpeg?raw=1)
# ## 3.2 Denmark
# Extramos diferentes posiciónes que pueden generarse para Dinamarca, juntamente con el promedio que generan y sus ratings.
# In[ ]:
Denmark = pd.DataFrame(np.array(get_summary_n(squad_list, squad_name, ['Denmark'])).reshape(-1,4),
columns = ['Nationality', 'Squad', 'Overall', 'Potential'])
Denmark.set_index('Nationality', inplace = True)
Denmark[['Overall', 'Potential']] = Denmark[['Overall', 'Potential']].astype(float)
Denmark
# Como podemos apreciar tenemos dos picos de estratégias, la formación 4-2-3-1 o 4-3-3; usando el feature 'Potential', podemos indicar que su mejor es usar 4-3-3. La cual indica que nuestro mejor score en general es 79.55, con un potencial máximo de 84.27
# In[ ]:
rating_433_DEN_Overall, best_list_433_DEN_Overall = get_best_squad_n(squad_433_strict, 'Denmark', 'Overall')
print('-Overall-')
print('Average rating: {:.1f}'.format(rating_433_DEN_Overall))
best_list_433_DEN_Overall
# In[ ]:
rating_433_DEN_Potential, best_list_433_DEN_Potential = get_best_squad_n(squad_433_strict, 'Denmark', 'Potential')
print('-Potential-')
print('Average rating: {:.1f}'.format(rating_433_DEN_Potential))
best_list_433_DEN_Potential
# ![schmeichel](https://github.com/romellfudi/ExploratoryDataAnalysis/blob/master/snapshot/schmeichel.jpg?raw=1)
# ## 3.3 Peru
# Extramos diferentes posiciónes que pueden generarse para Perú, juntamente con el promedio que generan y sus ratings.
# In[ ]:
Peru = pd.DataFrame(np.array(get_summary_n(squad_list, squad_name, ['Peru'])).reshape(-1,4),
columns = ['Nationality', 'Squad', 'Overall', 'Potential'])
Peru.set_index('Nationality', inplace = True)
Peru[['Overall', 'Potential']] = Peru[['Overall', 'Potential']].astype(float)
Peru
# Para nuestro Perú, tenemos con una puntuación general la formación 4-4-2 . De la misma forma su potencial se inclina ccon 76.27 sobre la media, seleccionando como esta la mejor formación que hoy en día cuenta.
# In[ ]:
rating_442_PER_Overall, best_list_442_PER_Overall = get_best_squad_n(squad_442_strict, 'Peru', 'Overall')
print('-Overall-')
print('Average rating: {:.1f}'.format(rating_442_PER_Overall))
best_list_442_PER_Overall
# In[ ]:
rating_442_PER_Potential, best_list_442_PER_Potential = get_best_squad_n(squad_442_strict, 'Peru', 'Potential')
print('-Potential-')
print('Average rating: {:.1f}'.format(rating_442_PER_Potential))
best_list_442_PER_Potential
# Pondré una foto del Capitan a pesar que no este en esta data ;)
# ![paolo](https://github.com/romellfudi/ExploratoryDataAnalysis/blob/master/snapshot/paolo.jpg?raw=1)
# ## 3.5 Australia
# Extramos diferentes posiciónes que pueden generarse para Australia, juntamente con el promedio que generan y sus ratings.
# In[ ]:
Australia = pd.DataFrame(np.array(get_summary_n(squad_list, squad_name, ['Australia'])).reshape(-1,4),
columns = ['Nationality', 'Squad', 'Overall', 'Potential'])
Australia.set_index('Nationality', inplace = True)
Australia[['Overall', 'Potential']] = Australia[['Overall', 'Potential']].astype(float)
Australia
# De forma similar Australia tiene un score general de 73.55 con la formación 4-3-3 actualmente, por otro lado el potencial máximo que puede alcanzar usando una formación 4-2-3-1 es de 77.90
# In[ ]:
rating_433_AU_Overall, best_list_433_AU_Overall = get_best_squad_n(squad_433_strict, 'Brazil', 'Overall')
print('-Overall-')
print('Average rating: {:.1f}'.format(rating_433_AU_Overall))
best_list_433_AU_Overall
# In[ ]:
rating_4312_AU_Potential, best_list_4312_AU_Potential = get_best_squad_n(squad_4312_strict, 'Australia', 'Potential')
print('-Potential-')
print('Average rating: {:.1f}'.format(rating_4312_AU_Potential))
best_list_4312_AU_Potential
# ![paolo](https://github.com/romellfudi/ExploratoryDataAnalysis/blob/master/snapshot/langerak.jpg?raw=1)
# ## 4 - Final Comparison
#
# A continuación muestro mediante barrras las puntuciones totales y potencial máximo, para tener una mejor panorama.
# In[ ]:
teams = ('France', 'Denmark', 'Peru', 'Australia')
index = np.arange(len(teams))
average_overall = [rating_433_FR_Overall, rating_433_DEN_Overall, rating_442_PER_Overall,rating_433_AU_Overall]
plt.figure(figsize=(16,8))
plt.barh(index, average_overall, align='center', alpha=0.5,color='brrb')
plt.yticks(index, teams, fontsize=20)
plt.ylabel('National Teams', fontsize=25)
plt.xlabel('Average Overall', fontsize=25)
plt.axvline(rating_442_PER_Overall)
plt.title('Average Overall Rating of Players', fontsize=30, fontweight='bold', y=1.05,)
plt.show()
# In[ ]:
index = np.arange(len(teams))
average_potential = [rating_442_FR_Potential, rating_433_DEN_Potential, rating_442_PER_Potential,rating_433_DEN_Potential]
plt.figure(figsize=(16,8))
plt.barh(index, average_potential, align='center',color='brrb', alpha=0.5)
plt.yticks(index, teams, fontsize=20)
plt.axvline(x=rating_442_PER_Potential)
plt.ylabel('National Teams', fontsize=25)
plt.xlabel('Average Potential', fontsize=25)
plt.title('Average Potential Rating of Players', fontsize=30, fontweight='bold', y=1.05,)
plt.show()
# In[ ]:
GroupC_Average
# In[ ]:
total_value = GroupC_Average.ValueNum.values * 1000
plt.figure(figsize=(16,8))
plt.barh(index, total_value, align='center', alpha=0.5, color='red')
plt.yticks(index, teams, fontsize=20)
plt.ylabel('National Teams', fontsize=25)
plt.xlabel('Total Value in Million Euros', fontsize=25)
plt.title('Total Value of Players', fontsize=30, fontweight='bold', y=1.05,)
plt.show()
# In[ ]:
average_wage = GroupC_Average.WageNum.values
plt.figure(figsize=(16,8))
plt.barh(index, average_wage, align='center', alpha=0.5, color='green')
plt.yticks(index, teams, fontsize=20)
plt.ylabel('National Teams', fontsize=25)
plt.xlabel('Average Wages in Thousand Euros (€)', fontsize=25)
plt.title('Average Wages of Players', fontsize=30, fontweight='bold', y=1.05,)
plt.show()
# # Conclusión
# Basandonos en el análisis realizado:
# * **Francia** tiene la máxima clasificación general media, seguido por **Australia y Dinamarca**.
# * **Francia** tiene el máximo score total, seguido by **Peru y Dinamarca**.
# * **Francia** tiene la recaudación máxima, seguido por **Peru**.
#
# Mi apuesta es la siguiente: **Francia y Dinamarca** pasan a octavos de finales, en tercer puesto se encontraría **Perú** del Grupo.
#
# Si les gusto compartantan este Notebook
# ## Copyright & License
#
# BoostTag E.I.R.L. Romell D.Z. ([@romellfudi](rdominguez@boosttag.com))
# All rights reserved
#
# https://portfolio.romellfudi.com/
#
# Copyright (c) 2018
# MIT. See the LICENSE file for the copyright notice.
# In[ ]: