Análisis de Datos en Python
Aprende a utilizar bibliotecas como NumPy, Pandas y Matplotlib para análisis, manipulación y visualización de datos en Python.
Cristian Escalante
Última actualización: 22 de mayo de 2025
Análisis de Datos en Python
El análisis de datos es una de las áreas donde Python destaca especialmente, gracias a su rico ecosistema de bibliotecas especializadas. En esta lección, aprenderemos a utilizar las principales herramientas para manipular, analizar y visualizar datos en Python.
Introducción al ecosistema de análisis de datos
Python se ha convertido en el lenguaje preferido para análisis de datos y ciencia de datos debido a bibliotecas como:
- NumPy: Para computación numérica eficiente con arrays multidimensionales
- Pandas: Para manipulación y análisis de datos estructurados
- Matplotlib: Para visualización de datos
- Seaborn: Para visualizaciones estadísticas avanzadas
- SciPy: Para computación científica
- Scikit-learn: Para aprendizaje automático
En esta lección, nos centraremos en las tres primeras, que forman la base de cualquier trabajo de análisis de datos en Python.
NumPy: Computación numérica eficiente
NumPy (Numerical Python) proporciona estructuras de datos y funciones para trabajar con arrays multidimensionales de manera eficiente.
Instalación de NumPy
pip install numpy
Arrays de NumPy
Los arrays de NumPy son más eficientes que las listas de Python para operaciones numéricas:
import numpy as np
# Crear un array a partir de una lista
lista = [1, 2, 3, 4, 5]
array = np.array(lista)
print(array) # [1 2 3 4 5]
# Crear arrays con valores específicos
zeros = np.zeros(5) # [0. 0. 0. 0. 0.]
ones = np.ones(5) # [1. 1. 1. 1. 1.]
rango = np.arange(0, 10, 2) # [0 2 4 6 8]
linspace = np.linspace(0, 1, 5) # [0. 0.25 0.5 0.75 1. ]
# Arrays multidimensionales
matriz = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
print(matriz)
# [[1 2 3]
# [4 5 6]
# [7 8 9]]
Operaciones con arrays
NumPy permite realizar operaciones vectorizadas, que son mucho más eficientes que los bucles:
# Operaciones aritméticas
a = np.array([1, 2, 3])
b = np.array([4, 5, 6])
print(a + b) # [5 7 9]
print(a * b) # [4 10 18]
print(a ** 2) # [1 4 9]
# Operaciones con matrices
A = np.array([[1, 2], [3, 4]])
B = np.array([[5, 6], [7, 8]])
print(A + B)
# [[ 6 8]
# [10 12]]
print(A.dot(B)) # Multiplicación de matrices
# [[19 22]
# [43 50]]
# Funciones universales (ufuncs)
print(np.sqrt(A)) # Raíz cuadrada de cada elemento
print(np.sin(a)) # Seno de cada elemento
print(np.log(a)) # Logaritmo natural de cada elemento
Indexación y slicing
NumPy proporciona formas poderosas de acceder a los elementos de un array:
# Crear un array 3x3
arr = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
# Acceder a elementos individuales (fila, columna)
print(arr[0, 0]) # 1
print(arr[1, 2]) # 6
# Slicing
print(arr[0:2, 1:3])
# [[2 3]
# [5 6]]
# Indexación booleana
print(arr > 5)
# [[False False False]
# [False False True]
# [ True True True]]
print(arr[arr > 5]) # [6 7 8 9]
Funciones estadísticas
NumPy incluye muchas funciones para análisis estadístico:
arr = np.array([1, 2, 3, 4, 5])
print(np.mean(arr)) # 3.0
print(np.median(arr)) # 3.0
print(np.std(arr)) # 1.4142135623730951
print(np.var(arr)) # 2.0
print(np.min(arr)) # 1
print(np.max(arr)) # 5
print(np.sum(arr)) # 15
Pandas: Manipulación y análisis de datos estructurados
Pandas es una biblioteca que proporciona estructuras de datos flexibles y herramientas para trabajar con datos estructurados.
Instalación de Pandas
pip install pandas
Series y DataFrames
Las dos estructuras de datos principales en Pandas son:
- Series: Array unidimensional etiquetado
- DataFrame: Tabla bidimensional con columnas potencialmente de diferentes tipos
import pandas as pd
# Crear una Series
s = pd.Series([1, 3, 5, np.nan, 6, 8])
print(s)
# 0 1.0
# 1 3.0
# 2 5.0
# 3 NaN
# 4 6.0
# 5 8.0
# dtype: float64
# Crear un DataFrame
datos = {
'nombre': ['Ana', 'Carlos', 'Elena', 'David'],
'edad': [28, 32, 25, 35],
'ciudad': ['Madrid', 'Barcelona', 'Sevilla', 'Valencia']
}
df = pd.DataFrame(datos)
print(df)
# nombre edad ciudad
# 0 Ana 28 Madrid
# 1 Carlos 32 Barcelona
# 2 Elena 25 Sevilla
# 3 David 35 Valencia
Lectura y escritura de datos
Pandas puede leer y escribir datos en diversos formatos:
# Leer un archivo CSV
# df = pd.read_csv('datos.csv')
# Leer un archivo Excel
# df = pd.read_excel('datos.xlsx')
# Escribir a un archivo CSV
# df.to_csv('salida.csv', index=False)
# Escribir a un archivo Excel
# df.to_excel('salida.xlsx', index=False)
Exploración de datos
Pandas ofrece muchas funciones para explorar y entender los datos:
# Crear un DataFrame de ejemplo más grande
df = pd.DataFrame({
'A': np.random.randn(10),
'B': np.random.randn(10),
'C': np.random.randn(10),
'D': np.random.choice(['X', 'Y', 'Z'], 10)
})
# Visualizar las primeras filas
print(df.head())
# Visualizar las últimas filas
print(df.tail(3))
# Información sobre el DataFrame
print(df.info())
# Estadísticas descriptivas
print(df.describe())
# Dimensiones
print(df.shape) # (filas, columnas)
Selección de datos
Pandas proporciona múltiples formas de seleccionar datos:
# Seleccionar una columna
print(df['A'])
# Seleccionar múltiples columnas
print(df[['A', 'B']])
# Seleccionar por posición
print(df.iloc[0]) # Primera fila
print(df.iloc[0:3, 1:3]) # Filas 0-2, columnas 1-2
# Seleccionar por etiqueta
print(df.loc[0:2, 'A':'C'])
Filtrado de datos
Podemos filtrar datos basándonos en condiciones:
# Filtrar filas donde A > 0
print(df[df['A'] > 0])
# Filtrar filas donde D es 'X'
print(df[df['D'] == 'X'])
# Filtros combinados
print(df[(df['A'] > 0) & (df['B'] < 0)])
Manejo de datos faltantes
Pandas tiene herramientas para detectar y manejar valores faltantes:
# Crear un DataFrame con valores faltantes
df_na = pd.DataFrame({
'A': [1, 2, np.nan, 4],
'B': [5, np.nan, np.nan, 8],
'C': [9, 10, 11, 12]
})
# Detectar valores faltantes
print(df_na.isna())
# Contar valores faltantes por columna
print(df_na.isna().sum())
# Eliminar filas con valores faltantes
print(df_na.dropna())
# Rellenar valores faltantes
print(df_na.fillna(0)) # Rellenar con 0
print(df_na.fillna(method='ffill')) # Propagar el último valor válido
Agrupación y agregación
Pandas permite agrupar datos y aplicar funciones de agregación:
# Crear un DataFrame para demostrar agrupación
df_ventas = pd.DataFrame({
'fecha': pd.date_range(start='2023-01-01', periods=10),
'tienda': ['A', 'B', 'A', 'B', 'A', 'B', 'A', 'B', 'A', 'B'],
'producto': ['X', 'X', 'Y', 'Y', 'Z', 'Z', 'X', 'X', 'Y', 'Y'],
'ventas': np.random.randint(100, 1000, 10),
'unidades': np.random.randint(1, 10, 10)
})
# Agrupar por tienda y calcular la suma de ventas
print(df_ventas.groupby('tienda')['ventas'].sum())
# Agrupar por tienda y producto
print(df_ventas.groupby(['tienda', 'producto']).agg({
'ventas': 'sum',
'unidades': 'mean'
}))
Operaciones con DataFrames
Pandas facilita operaciones comunes en análisis de datos:
# Ordenar datos
print(df_ventas.sort_values('ventas', ascending=False))
# Aplicar funciones a columnas
df_ventas['precio_unitario'] = df_ventas['ventas'] / df_ventas['unidades']
# Pivot tables
pivot = df_ventas.pivot_table(
values='ventas',
index='tienda',
columns='producto',
aggfunc='sum'
)
print(pivot)
# Unir DataFrames
df1 = pd.DataFrame({'clave': ['A', 'B', 'C'], 'valor1': [1, 2, 3]})
df2 = pd.DataFrame({'clave': ['A', 'B', 'D'], 'valor2': [4, 5, 6]})
# Merge (similar a SQL join)
print(pd.merge(df1, df2, on='clave', how='inner'))
print(pd.merge(df1, df2, on='clave', how='outer'))
Matplotlib: Visualización de datos
Matplotlib es la biblioteca de visualización más utilizada en Python.
Instalación de Matplotlib
pip install matplotlib
Gráficos básicos
import matplotlib.pyplot as plt
# Datos de ejemplo
x = np.linspace(0, 10, 100)
y = np.sin(x)
# Crear un gráfico de líneas
plt.figure(figsize=(10, 6))
plt.plot(x, y, 'b-', label='sen(x)')
plt.title('Función Seno')
plt.xlabel('x')
plt.ylabel('sen(x)')
plt.grid(True)
plt.legend()
# plt.savefig('seno.png') # Guardar el gráfico
plt.show()
Múltiples gráficos
plt.figure(figsize=(10, 6))
plt.subplot(2, 1, 1) # 2 filas, 1 columna, gráfico 1
plt.plot(x, np.sin(x), 'b-')
plt.title('Función Seno')
plt.grid(True)
plt.subplot(2, 1, 2) # 2 filas, 1 columna, gráfico 2
plt.plot(x, np.cos(x), 'r-')
plt.title('Función Coseno')
plt.grid(True)
plt.tight_layout() # Ajustar espaciado
plt.show()
Tipos de gráficos comunes
# Datos para los gráficos
categorias = ['A', 'B', 'C', 'D', 'E']
valores = [25, 40, 30, 55, 15]
# Gráfico de barras
plt.figure(figsize=(12, 10))
plt.subplot(2, 2, 1)
plt.bar(categorias, valores)
plt.title('Gráfico de Barras')
# Gráfico de dispersión
plt.subplot(2, 2, 2)
x = np.random.rand(50)
y = np.random.rand(50)
colores = np.random.rand(50)
tamaños = 1000 * np.random.rand(50)
plt.scatter(x, y, c=colores, s=tamaños, alpha=0.5)
plt.title('Gráfico de Dispersión')
# Gráfico de pastel
plt.subplot(2, 2, 3)
plt.pie(valores, labels=categorias, autopct='%1.1f%%', startangle=90)
plt.axis('equal') # Para que el círculo sea redondo
plt.title('Gráfico de Pastel')
# Histograma
plt.subplot(2, 2, 4)
datos = np.random.randn(1000)
plt.hist(datos, bins=30)
plt.title('Histograma')
plt.tight_layout()
plt.show()
Visualización con Pandas
Pandas integra funcionalidades de Matplotlib para visualizar datos directamente:
# Crear un DataFrame de ejemplo
df = pd.DataFrame(np.random.randn(100, 4), columns=['A', 'B', 'C', 'D'])
df = df.cumsum() # Suma acumulativa para ver tendencias
# Gráfico de líneas
df.plot(figsize=(10, 6))
plt.title('Gráfico de líneas con Pandas')
plt.grid(True)
plt.show()
# Gráfico de barras
df_barras = pd.DataFrame({
'grupo': ['A', 'B', 'C', 'A', 'B', 'C'],
'datos1': np.random.rand(6) * 10,
'datos2': np.random.rand(6) * 100
})
df_barras.plot.bar(x='grupo', figsize=(10, 6))
plt.title('Gráfico de barras con Pandas')
plt.grid(True)
plt.show()
# Histograma
df['A'].plot.hist(bins=20, alpha=0.5, figsize=(10, 6))
plt.title('Histograma con Pandas')
plt.grid(True)
plt.show()
# Gráfico de dispersión
df.plot.scatter(x='A', y='B', figsize=(10, 6))
plt.title('Gráfico de dispersión con Pandas')
plt.grid(True)
plt.show()
Ejemplo práctico: Análisis de un conjunto de datos real
Vamos a analizar un conjunto de datos de ejemplo para aplicar lo aprendido:
# Crear un conjunto de datos simulado de ventas
np.random.seed(42)
fechas = pd.date_range(start='2022-01-01', end='2022-12-31', freq='D')
n = len(fechas)
datos_ventas = pd.DataFrame({
'fecha': fechas,
'ventas': np.random.randint(100, 1000, n),
'categoria': np.random.choice(['Electrónica', 'Ropa', 'Hogar', 'Alimentos'], n),
'region': np.random.choice(['Norte', 'Sur', 'Este', 'Oeste'], n),
'promocion': np.random.choice([True, False], n)
})
# Añadir una columna de mes y día de la semana
datos_ventas['mes'] = datos_ventas['fecha'].dt.month_name()
datos_ventas['dia_semana'] = datos_ventas['fecha'].dt.day_name()
# 1. Exploración inicial
print(datos_ventas.head())
print(datos_ventas.info())
print(datos_ventas.describe())
# 2. Análisis por categoría
ventas_por_categoria = datos_ventas.groupby('categoria')['ventas'].agg(['sum', 'mean', 'count'])
print(ventas_por_categoria)
# 3. Análisis por región
ventas_por_region = datos_ventas.groupby('region')['ventas'].sum()
print(ventas_por_region)
# 4. Análisis temporal
ventas_mensuales = datos_ventas.groupby(datos_ventas['fecha'].dt.month)['ventas'].sum()
ventas_por_dia_semana = datos_ventas.groupby('dia_semana')['ventas'].mean()
# 5. Impacto de promociones
ventas_con_promo = datos_ventas[datos_ventas['promocion']]['ventas'].mean()
ventas_sin_promo = datos_ventas[~datos_ventas['promocion']]['ventas'].mean()
print(f"Ventas promedio con promoción: {ventas_con_promo:.2f}")
print(f"Ventas promedio sin promoción: {ventas_sin_promo:.2f}")
# 6. Visualizaciones
plt.figure(figsize=(15, 10))
# 6.1 Ventas por categoría
plt.subplot(2, 2, 1)
ventas_por_categoria['sum'].plot.bar()
plt.title('Ventas totales por categoría')
plt.xticks(rotation=45)
plt.grid(axis='y')
# 6.2 Ventas por región
plt.subplot(2, 2, 2)
ventas_por_region.plot.pie(autopct='%1.1f%%')
plt.title('Distribución de ventas por región')
plt.ylabel('')
# 6.3 Tendencia temporal
plt.subplot(2, 2, 3)
datos_ventas.groupby(datos_ventas['fecha'].dt.month)['ventas'].sum().plot()
plt.title('Ventas mensuales')
plt.grid(True)
plt.xticks(range(1, 13))
# 6.4 Ventas por día de la semana
plt.subplot(2, 2, 4)
dias_orden = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday']
ventas_por_dia_semana = ventas_por_dia_semana.reindex(dias_orden)
ventas_por_dia_semana.plot.bar()
plt.title('Ventas promedio por día de la semana')
plt.xticks(rotation=45)
plt.grid(axis='y')
plt.tight_layout()
plt.show()
# 7. Análisis cruzado: categoría por región
tabla_cruzada = pd.crosstab(
datos_ventas['categoria'],
datos_ventas['region'],
values=datos_ventas['ventas'],
aggfunc='sum'
)
print(tabla_cruzada)
# Visualización de la tabla cruzada
plt.figure(figsize=(12, 8))
tabla_cruzada.plot.bar(stacked=True)
plt.title('Ventas por categoría y región')
plt.xlabel('Categoría')
plt.ylabel('Ventas')
plt.legend(title='Región')
plt.grid(axis='y')
plt.show()
Integración con otras bibliotecas
El ecosistema de análisis de datos en Python es muy amplio. Algunas bibliotecas adicionales que puedes explorar:
- Seaborn: Para visualizaciones estadísticas más avanzadas
- Plotly: Para gráficos interactivos
- Scikit-learn: Para aprendizaje automático
- SciPy: Para computación científica
- Statsmodels: Para modelos estadísticos
Mejores prácticas en análisis de datos
- Entender los datos antes de analizarlos: Explora y comprende la estructura, tipos y distribución de tus datos.
- Limpiar los datos adecuadamente: Maneja valores faltantes, duplicados y outliers.
- Documentar el proceso de análisis: Mantén un registro claro de los pasos realizados.
- Visualizar para comprender: Usa gráficos para entender patrones y relaciones.
- Validar resultados: Verifica tus conclusiones con diferentes enfoques.
- Optimizar para rendimiento: Usa las funciones vectorizadas de NumPy y Pandas en lugar de bucles.
- Mantener el código organizado: Usa funciones y clases para estructurar tu análisis.
Ejercicios prácticos
- Carga un conjunto de datos CSV de tu elección y realiza un análisis exploratorio completo.
- Crea visualizaciones que muestren las relaciones entre diferentes variables en el conjunto de datos.
- Implementa un análisis de series temporales para datos que varían con el tiempo.
- Realiza un análisis de correlación entre variables numéricas en un conjunto de datos.
- Crea un dashboard simple con múltiples visualizaciones que resuman un conjunto de datos.
En la próxima lección, exploraremos las expresiones regulares en Python, una herramienta poderosa para trabajar con patrones de texto.