Módulo 1: El calentamiento - Exploración profunda de datos
1. El calentamiento: preparando el análisis
En la formación básica, construimos unos cimientos sólidos de Python. Ahora, en este curso intermedio, vamos a empezar a construir sobre ellos. Nuestro objetivo ya no es solo escribir código, sino empezar a pensar como un analista de datos.
El primer paso en cualquier proyecto de análisis, antes de buscar patrones o crear visualizaciones, es siempre el mismo: entender a fondo los datos con los que estamos trabajando. Así como un equipo calienta y estudia al rival antes de un partido, nosotros debemos “calentar” y realizar una exploración inicial de nuestro set de datos.
Este proceso, conocido como Análisis Exploratorio de Datos (EDA, por sus siglas en inglés), es fundamental. Nos permite familiarizarnos con la estructura de la información, identificar posibles problemas y empezar a formular las preguntas correctas.
En este primer módulo, nos sumergiremos en un set de datos de eventos de un partido completo. Aprenderás a usar las funciones esenciales de Pandas para inspeccionarlo y entenderlo, una habilidad que te servirá de base para todo lo que construiremos a continuación.
2. Cargando los datos del partido
Para nuestro análisis, no usaremos un archivo CSV estático. Vamos a obtener datos frescos y reales directamente desde una fuente pública gracias a una librería de Python llamada underdata
. Esta herramienta nos conecta con los datos de eventos del sitio Understat.com, una fuente muy rica de información estadística del fútbol.
Si seguiste la formación básica, ya la tienes instalada. Si no, o si estás empezando desde aquí, el primer paso es instalarla en tu entorno.
Abre tu terminal y ejecuta el siguiente comando:
pip install underdata
Una vez instalada, ya podemos usarla en nuestro Jupyter Notebook para cargar los datos de un partido completo.
En tu notebook:
Primero, importamos las librerías que necesitaremos: pandas
para manejar los datos y Understat
desde nuestra nueva librería.
import pandas as pd
from underdata import Understat
A continuación, creamos una “instancia” de Understat para la liga que nos interesa, en este caso, la Premier League inglesa (“EPL”).
# Creamos una instancia para la Premier League
epl = Understat(league="EPL")
Finalmente, le pedimos que nos entregue los datos de un partido específico usando su ID. Usaremos un partido como ejemplo para que todos trabajemos con los mismos datos. El resultado se guardará en una variable que, por convención, llamaremos match_data
.
# Obtenemos los datos del partido (usaremos un ID de ejemplo)
# La función devuelve un DataFrame de Pandas directamente
match_data = epl.get_match_data(match_id=23722)
# Imprimimos la forma del DataFrame para ver cuántas filas y columnas tiene
print(f"Datos cargados con éxito. El DataFrame tiene {match_data.shape[0]} filas y {match_data.shape[1]} columnas.")
Con solo unas pocas líneas de código, hemos cargado miles de eventos de un partido real en un DataFrame de Pandas, listos para ser analizados. En la siguiente sección, aprenderemos a realizar nuestra primera inspección para entender la estructura y el contenido de esta tabla de datos.
3. La primera inspección: .info()
y .describe()
Ya hemos cargado miles de filas de datos de un partido en nuestra variable match_data
. Antes de intentar analizar o filtrar cualquier cosa, un buen analista siempre se toma un momento para hacer un “reconocimiento del terreno”. Para ello, Pandas nos ofrece dos comandos fundamentales que nos dan una radiografía instantánea de nuestro DataFrame.
La ficha técnica del partido con .info()
El método .info()
nos da un resumen técnico y estructural de nuestros datos. Es la primera herramienta que debes usar al cargar un nuevo DataFrame.
En tu Jupyter Notebook, añade y ejecuta la siguiente celda:
# Muestra un resumen técnico del DataFrame
match_data.info()
La salida te mostrará información valiosa:
- El número total de filas (entradas) y columnas.
- Una lista de todas las columnas con su nombre.
- El número de valores no nulos en cada columna. Esto es muy importante, ya que nos permite detectar rápidamente si tenemos datos faltantes.
- El tipo de dato (
Dtype
) de cada columna (object
para texto,int64
para números enteros,float64
para números con decimales).
Esta función es tu primera línea de defensa para entender la calidad y la estructura de los datos con los que vas a trabajar.
El resumen estadístico con .describe()
Mientras que .info()
nos da la estructura, el método .describe()
nos da un resumen estadístico de todas las columnas numéricas. Es una forma rápida de entender la distribución de tus datos.
Ejecútalo en una nueva celda:
# Muestra estadísticas descriptivas de las columnas numéricas
match_data.describe()
La tabla resultante te mostrará, para cada columna numérica (como las coordenadas x
, y
o el xG
):
count
: El número de valores.mean
: El promedio.std
: La desviación estándar (una medida de la dispersión de los datos).min
ymax
: El valor mínimo y máximo.25%
,50%
,75%
: Los percentiles, que te ayudan a entender cómo se distribuyen los datos.
Con solo estos dos comandos, ya tienes una comprensión mucho más profunda de tu set de datos. Sabes qué información contiene, qué formato tiene y cómo se distribuyen sus valores numéricos. En la siguiente sección, nos enfocaremos en explorar las columnas que no son numéricas.
4. Explorando las categorías con .value_counts()
Los métodos .info()
y .describe()
son excelentes para darnos una visión general, pero a menudo queremos profundizar en columnas específicas, especialmente en las que no son numéricas. Para esto, una de las herramientas más útiles es el método .value_counts()
.
Este comando cuenta cuántas veces aparece cada valor único en una columna y nos devuelve una tabla ordenada, lo que es perfecto para responder preguntas como:
- ¿Qué tipo de evento ocurrió más veces en el partido?
- ¿Qué jugador tuvo más intervenciones (más eventos asociados)?
- ¿Qué equipo tuvo más acciones registradas?
Vamos a aplicarlo a nuestro match_data
.
En tu Jupyter Notebook:
Empecemos por analizar la columna result
, que nos dice el tipo de cada evento.
# Contamos la frecuencia de cada tipo de evento
conteo_de_eventos = match_data['result'].value_counts()
print("--- Frecuencia por Tipo de Evento ---")
print(conteo_de_eventos.head(5)) # Mostramos los 5 más comunes
Salida de ejemplo:
--- Frecuencia por Tipo de Evento ---
result
Pass 1050
Shot 25
Carry 15
TakeOn 12
Foul 10
Name: count, dtype: int64
Esta simple línea de código ya nos da un insight valioso: la gran mayoría de los eventos en un partido son pases.
Ahora, hagamos lo mismo para la columna player
para ver qué jugadores tuvieron más participación en el juego.
# Contamos cuántos eventos tiene registrados cada jugador
intervenciones_por_jugador = match_data['player'].value_counts()
print("\n--- Top 5 Jugadores con Más Intervenciones ---")
print(intervenciones_por_jugador.head())
Salida de ejemplo:
--- Top 5 Jugadores con Más Intervenciones ---
player
Trent Alexander-Arnold 150
Virgil van Dijk 130
Alexis Mac Allister 125
Andrew Robertson 110
Alisson Becker 90
Name: count, dtype: int64
Esta técnica es la base para empezar a crear rankings y a comparar jugadores o equipos. Con .value_counts()
, has añadido una herramienta de exploración fundamental a tu repertorio.
En la siguiente sección, cerraremos este primer módulo con las conclusiones y un avance de lo que nos espera.
5. Conclusiones y el siguiente paso
Has completado el “calentamiento”. Este primer módulo, aunque no hemos realizado análisis complejos, es uno de los más importantes. Has aprendido el proceso fundamental que todo analista de datos realiza al enfrentarse a un nuevo set de datos: la exploración.
Ahora tienes la habilidad de:
- Cargar datos desde una fuente externa directamente a un DataFrame.
- Usar
.info()
para obtener una radiografía técnica de la estructura y la calidad de los datos. - Usar
.describe()
para entender la distribución estadística de las variables numéricas. - Usar
.value_counts()
para explorar y cuantificar los datos categóricos.
Este proceso de inspección inicial no es un simple trámite; es la base sobre la que se construyen todos los análisis exitosos. Conocer tus datos es el primer paso para poder hacerles las preguntas correctas.
En el Módulo 2, dejaremos la exploración y nos pondremos manos a la obra con la manipulación. Usaremos el conocimiento que hemos ganado sobre nuestros datos para empezar a filtrarlos y a aislar la información específica que necesitamos para responder nuestras primeras preguntas tácticas.