1. Carga de datos:¶

- Utiliza la base de datos 'base_players_arg.csv'.¶

- Carga los datos en un DataFrame de Pandas¶

In [1]:
#importación librerías
import pandas as pd
In [2]:
#Carga los datos en un DataFrame de Pandas
df = pd.read_csv('base_players_arg.csv', header = 0)

2. Exploración inicial:¶

- Visualiza las primeras filas del dataset.¶

In [3]:
df.head(10)
Out[3]:
playerId competitionId seasonId position_code position_name total_matches total_matchesInStart total_matchesSubstituted total_matchesComingOff total_minutesOnField ... label date dateutc status_1 competitionId_2 seasonId_2 roundId_1 gameweek contractExpiration agencies
0 86432 146 188660 gk Goalkeeper 1.0 1.0 0.0 0.0 98.0 ... Barracas Central - Instituto, 3 - 0 2023-05-05 20:30:00+00:00 2023-05-05 18:30:00+00:00 Played 146 188660 4428177 15 2024-12-31 Agustin Grillo
1 700015 146 188660 dmf Defensive Midfielder 1.0 0.0 0.0 1.0 55.0 ... Gimnasia La Plata - Colón, 1 - 0 2023-12-01 21:00:00+00:00 2023-12-01 20:00:00+00:00 Played 146 188660 4431000 1 2024-12-31 NaN
2 893490 146 188660 lb5 Left Back (5 at the back) 1.0 1.0 1.0 0.0 77.0 ... Instituto - Barracas Central, 0 - 0 2023-11-14 01:00:00+00:00 2023-11-14 00:00:00+00:00 Played 146 188660 4429310 13 NaN NaN
3 708568 146 188660 dmf Defensive Midfielder 1.0 0.0 0.0 1.0 14.0 ... Instituto - Barracas Central, 0 - 0 2023-11-14 01:00:00+00:00 2023-11-14 00:00:00+00:00 Played 146 188660 4429310 13 2025-12-31 NaN
4 418027 146 188660 cf Striker 1.0 1.0 1.0 0.0 16.0 ... Barracas Central - Instituto, 3 - 0 2023-05-05 20:30:00+00:00 2023-05-05 18:30:00+00:00 Played 146 188660 4428177 15 2024-12-31 Proyecta Players
5 418027 146 188660 cf Striker 1.0 1.0 1.0 0.0 77.0 ... Instituto - Barracas Central, 0 - 0 2023-11-14 01:00:00+00:00 2023-11-14 00:00:00+00:00 Played 146 188660 4429310 13 2024-12-31 Proyecta Players
6 88934 146 188660 rdmf Right Defensive Midfielder 1.0 1.0 1.0 0.0 85.0 ... Instituto - Barracas Central, 0 - 0 2023-11-14 01:00:00+00:00 2023-11-14 00:00:00+00:00 Played 146 188660 4429310 13 2024-12-31 NaN
7 88934 146 188660 dmf Defensive Midfielder 1.0 1.0 1.0 0.0 85.0 ... Barracas Central - Instituto, 3 - 0 2023-05-05 20:30:00+00:00 2023-05-05 18:30:00+00:00 Played 146 188660 4428177 15 2024-12-31 NaN
8 364018 146 188660 lcb Left Centre Back 1.0 1.0 0.0 0.0 98.0 ... Barracas Central - Instituto, 3 - 0 2023-05-05 20:30:00+00:00 2023-05-05 18:30:00+00:00 Played 146 188660 4428177 15 2024-12-31 Marco Vanzini CAASTELLAR GROUP
9 778525 146 188660 rcmf Right Centre Midfielder 1.0 1.0 0.0 0.0 104.0 ... Gimnasia La Plata - Colón, 1 - 0 2023-12-01 21:00:00+00:00 2023-12-01 20:00:00+00:00 Played 146 188660 4431000 1 NaN NaN

10 rows × 314 columns

In [4]:
#Conocer número de filas y número de columnas
df.shape
Out[4]:
(38873, 314)

- Identifica los tipos de datos de cada columna.¶

In [5]:
print(df.dtypes)
playerId               int64
competitionId          int64
seasonId               int64
position_code         object
position_name         object
                       ...  
seasonId_2             int64
roundId_1              int64
gameweek               int64
contractExpiration    object
agencies              object
Length: 314, dtype: object

3. Limpieza de datos:¶

- Detecta y maneja valores nulos (rellenarlos, eliminarlos o reemplazarlos)¶

In [6]:
# Mostrar cuántos valores nulos hay en cada columna
print(df.isnull().sum())
playerId                  0
competitionId             0
seasonId                  0
position_code             0
position_name             0
                      ...  
seasonId_2                0
roundId_1                 0
gameweek                  0
contractExpiration     5471
agencies              18268
Length: 314, dtype: int64
In [7]:
#Eliminar filas con valores nulos
df_sin_nulos = df.dropna()
In [8]:
df_sin_nulos.head(10)
Out[8]:
playerId competitionId seasonId position_code position_name total_matches total_matchesInStart total_matchesSubstituted total_matchesComingOff total_minutesOnField ... label date dateutc status_1 competitionId_2 seasonId_2 roundId_1 gameweek contractExpiration agencies

0 rows × 314 columns

Al eliminar las filas con valores nulos, observamos que todas contienen al menos un valor nulo, por lo que esta opción queda descartada.¶

In [9]:
# Identificar columnas con valores nulos
columnas_con_nulos = df.columns[df.isnull().any()].tolist()
In [10]:
# Mostrar las columnas que tienen al menos un valor nulo
print("Columnas que contienen valores nulos:")
print(columnas_con_nulos)
Columnas que contienen valores nulos:
['teamId', 'middleName', 'birthDate', 'age', 'foot', 'currentTeamId', 'currentNationalTeamId', 'imageDataURL', 'teamIdFormador', 'currentTeamIsFormador', 'condicionFormados', 'ldp_player_id', 'contractExpiration', 'agencies']
In [11]:
# Determinar cuántos valores nulos tiene cada columna
if columnas_con_nulos:
    print("\nCantidad de valores nulos por columna:")
    for columna in columnas_con_nulos:
        num_nulos = df[columna].isnull().sum()
        print(f"{columna}: {num_nulos} valores nulos")
else:
    print("No hay columnas con valores nulos en el DataFrame.")
Cantidad de valores nulos por columna:
teamId: 257 valores nulos
middleName: 38873 valores nulos
birthDate: 1 valores nulos
age: 1 valores nulos
foot: 112 valores nulos
currentTeamId: 714 valores nulos
currentNationalTeamId: 35658 valores nulos
imageDataURL: 88 valores nulos
teamIdFormador: 638 valores nulos
currentTeamIsFormador: 714 valores nulos
condicionFormados: 31677 valores nulos
ldp_player_id: 30 valores nulos
contractExpiration: 5471 valores nulos
agencies: 18268 valores nulos
In [12]:
# Mostrar el tipo de datos de cada columna con valores nulos
df.dtypes[columnas_con_nulos]
Out[12]:
teamId                   float64
middleName               float64
birthDate                 object
age                      float64
foot                      object
currentTeamId            float64
currentNationalTeamId    float64
imageDataURL              object
teamIdFormador           float64
currentTeamIsFormador     object
condicionFormados         object
ldp_player_id            float64
contractExpiration        object
agencies                  object
dtype: object

Eliminar la columna middleName debido a que no tiene registros¶

In [13]:
df.drop(columns=["middleName"], inplace=True)

Remplazar los nulos en algunas columnas tipo object con el texto: "Desconocido"¶

In [14]:
df[["foot", "imageDataURL", "condicionFormados", "agencies"]] = df[["foot", "imageDataURL", "condicionFormados", "agencies"]].fillna("Desconocido")

Convertir la columna birthDate a formato datetime¶

In [15]:
df["birthDate"] = pd.to_datetime(df["birthDate"], errors='coerce')

Convertir la columna contractExpiration a formato datetime¶

In [16]:
df["contractExpiration"] = pd.to_datetime(df["contractExpiration"], errors='coerce')

En la columna birthDate reemplazar los valores NaT (valores nulos o inválidos en formato datetime) con una fecha predeterminada (en este caso '1900-01-01')¶

In [17]:
df["birthDate"].fillna(pd.to_datetime("1900-01-01"), inplace=True)

En la columna contractExpiration reemplazar los valores NaT (valores nulos o inválidos en formato datetime) con una fecha predeterminada (en este caso '1900-01-01')¶

In [18]:
df["contractExpiration"].fillna(pd.to_datetime("1900-01-01"), inplace=True)

El registro faltante en la columna age lo rellenamos con la media de dicha columna¶

In [19]:
df["age"].fillna(df["age"].mean(), inplace=True)

Rellenar los valores nulos con -1 en las columnas teamId, currentTeamId, currentNationalTeamId, teamIdFormador y ldp_player_id¶

In [20]:
df[["teamId", "currentTeamId", "currentNationalTeamId", "teamIdFormador", "ldp_player_id"]] = df[["teamId", "currentTeamId", "currentNationalTeamId", "teamIdFormador", "ldp_player_id"]].fillna(-1)

currentTeamIsFormador convertir a bool y reemplazar NaN (nulos) con False¶

In [21]:
df["currentTeamIsFormador"] = df["currentTeamIsFormador"].astype(bool)

- Identifica y elimina valores duplicados.¶

El dataset contiene estadísticas de cada jugador por partido, por lo que es normal que haya múltiples filas para un mismo jugador. En este caso, el jugador por sí solo no puede ser considerado como clave primaria.

Los identificadores utilizados para partidos y jugadores son matchId y playerId. Para definir una clave primaria, combinaremos ambos campos.

Para detectar posibles duplicados, agregamos una nueva columna que resulta de la unión de estos dos identificadores.

Solo para el cálculo de esta nueva columna, convertimos ambas variables a formato string y así generamos nuestra clave primaria.

In [23]:
df['primary_key'] = df['playerId'].astype(str) + '_' + df['matchId'].astype(str)
In [24]:
df.head()
Out[24]:
playerId competitionId seasonId position_code position_name total_matches total_matchesInStart total_matchesSubstituted total_matchesComingOff total_minutesOnField ... date dateutc status_1 competitionId_2 seasonId_2 roundId_1 gameweek contractExpiration agencies primary_key
0 86432 146 188660 gk Goalkeeper 1.0 1.0 0.0 0.0 98.0 ... 2023-05-05 20:30:00+00:00 2023-05-05 18:30:00+00:00 Played 146 188660 4428177 15 2024-12-31 Agustin Grillo 86432_5420312
1 700015 146 188660 dmf Defensive Midfielder 1.0 0.0 0.0 1.0 55.0 ... 2023-12-01 21:00:00+00:00 2023-12-01 20:00:00+00:00 Played 146 188660 4431000 1 2024-12-31 Desconocido 700015_5543867
2 893490 146 188660 lb5 Left Back (5 at the back) 1.0 1.0 1.0 0.0 77.0 ... 2023-11-14 01:00:00+00:00 2023-11-14 00:00:00+00:00 Played 146 188660 4429310 13 1900-01-01 Desconocido 893490_5463692
3 708568 146 188660 dmf Defensive Midfielder 1.0 0.0 0.0 1.0 14.0 ... 2023-11-14 01:00:00+00:00 2023-11-14 00:00:00+00:00 Played 146 188660 4429310 13 2025-12-31 Desconocido 708568_5463692
4 418027 146 188660 cf Striker 1.0 1.0 1.0 0.0 16.0 ... 2023-05-05 20:30:00+00:00 2023-05-05 18:30:00+00:00 Played 146 188660 4428177 15 2024-12-31 Proyecta Players 418027_5420312

5 rows × 314 columns

In [25]:
df['primary_key'].nunique()
Out[25]:
22873

Usamos el método groupby para identificar las claves primarias que aparecen más de una vez.

In [26]:
df.groupby('primary_key')['primary_key'].count().sort_values(ascending = False)
Out[26]:
primary_key
582416_5420331    3
543341_5578281    3
543341_5463605    3
543341_5420459    3
543341_5420446    3
                 ..
662914_5463628    1
218643_5420323    1
4376_5420119      1
662914_5578170    1
640425_5420422    1
Name: primary_key, Length: 22873, dtype: int64

Inicialmente, contábamos con 38,873 filas, pero solo 22,873 registros únicos según la clave primaria. El método drop_duplicates permite eliminar filas duplicadas en función de una columna específica. En este caso, lo aplicamos sobre primary_key para conservar únicamente los registros únicos.

In [27]:
df.drop_duplicates(subset=['primary_key'], inplace = True)
In [28]:
df.shape
Out[28]:
(22873, 314)

4. Análisis básico:¶

- ¿Cuántos jugadores únicos hay en la base de datos?¶

In [31]:
df['playerId'].nunique()
Out[31]:
1267

- ¿Cuál es la edad promedio de los jugadores?¶

In [43]:
df_jugadores = df.drop_duplicates(subset=['playerId'])
df_jugadores['age'].mean()
Out[43]:
26.44324393435529

- ¿Cuáles son las posiciones mas comunes?¶

In [44]:
df_jugadores['position_name'].value_counts().head(5)
Out[44]:
position_name
Striker                    188
Right Centre Midfielder     93
Left Centre Midfielder      85
Left Back                   79
Goalkeeper                  73
Name: count, dtype: int64

5. Bonus (opcional):¶

- Visualiza la distribución de edades de los jugadores con un histograma.¶

In [45]:
import matplotlib.pyplot as plt
import seaborn as sns
In [50]:
# Crear el histograma
plt.figure(figsize=(10, 6))
sns.histplot(df_jugadores['age'], bins=20, kde=True, color='blue')
Out[50]:
<Axes: xlabel='age', ylabel='Count'>
In [ ]: