Data Science in Brief
Herramientas fundamentales para análisis de datos con Python
Python se ha convertido en el lenguaje dominante en Data Science, Machine Learning e Inteligencia Artificial. Su ecosistema de bibliotecas especializadas permite a los científicos de datos realizar desde simples análisis exploratorios hasta complejos modelos predictivos con una sintaxis clara y eficiente.
En este capítulo exploraremos las herramientas fundamentales del Data Science en Python: IPython y Jupyter para desarrollo interactivo, NumPy para computación numérica, pandas para manipulación de datos, y matplotlib para visualización.
El Ecosistema de Data Science
El ecosistema de Python para Data Science está construido sobre bibliotecas especializadas que trabajan en conjunto. Cada una resuelve un problema específico y se integra perfectamente con las demás.
Bibliotecas Fundamentales
Instalación del Entorno
# Crear entorno virtual $ python -m venv datascience_env $ source datascience_env/bin/activate # Instalar bibliotecas fundamentales $ pip install numpy pandas matplotlib jupyter # Iniciar Jupyter Notebook $ jupyter notebook
conda para proyectos complejos, ya que maneja mejor las dependencias de bibliotecas científicas con componentes en C/C++.
IPython y Jupyter Notebooks
IPython (Interactive Python) proporciona un shell interactivo mejorado con características como autocompletado, historial persistente y comandos mágicos. Jupyter Notebooks extiende esta funcionalidad a un entorno web donde puedes combinar código, texto y visualizaciones.
Características de IPython
Comandos Mágicos Esenciales
# Medir tiempo de ejecución %timeit [x**2 for x in range(1000)] # Ver historial de comandos %history # Cargar archivo externo %load my_script.py # Ejecutar script externo %run my_script.py # Ver documentación ?len # Ver código fuente ??my_function # Listar variables en memoria %who %whos # Versión detallada # Limpiar variables %reset
Estructura de un Notebook
.ipynb pueden compartirse y visualizarse en GitHub.
NumPy: Computación Numérica
NumPy es el pilar fundamental de la computación científica en Python. Su estructura principal, el ndarray, permite operaciones vectorizadas extremadamente eficientes sobre grandes conjuntos de datos numéricos.
Creación de Arrays
import numpy as np # Crear arrays desde listas arr1d = np.array([1, 2, 3, 4, 5]) arr2d = np.array([[1, 2, 3], [4, 5, 6]]) # Arrays especiales zeros = np.zeros((3, 4)) # Matriz 3x4 de ceros ones = np.ones((2, 3)) # Matriz 2x3 de unos identity = np.eye(4) # Matriz identidad 4x4 random = np.random.rand(3, 3) # Matriz 3x3 aleatoria # Rangos y secuencias rango = np.arange(0, 10, 2) # [0, 2, 4, 6, 8] lineal = np.linspace(0, 1, 5) # [0, 0.25, 0.5, 0.75, 1] # Propiedades del array print(arr2d.shape) # (2, 3) print(arr2d.dtype) # int64 print(arr2d.ndim) # 2 print(arr2d.size) # 6
Operaciones Vectorizadas
La vectorización permite realizar operaciones sobre arrays completos sin loops explícitos, aprovechando optimizaciones en C a nivel interno.
import numpy as np a = np.array([1, 2, 3, 4]) b = np.array([10, 20, 30, 40]) # Operaciones elemento a elemento print(a + b) # [11, 22, 33, 44] print(a * b) # [10, 40, 90, 160] print(a ** 2) # [1, 4, 9, 16] print(np.sqrt(a)) # [1.0, 1.414, 1.732, 2.0] # Funciones de agregación print(a.sum()) # 10 print(a.mean()) # 2.5 print(a.std()) # 1.118 print(a.min()) # 1 print(a.max()) # 4 # Broadcasting: operar arrays de diferente forma matrix = np.array([[1, 2, 3], [4, 5, 6]]) print(matrix + 10) # Suma 10 a cada elemento
[14 15 16]]
Indexación y Slicing
import numpy as np arr = np.array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]]) # Indexación básica print(arr[0, 0]) # 1 (primera fila, primera columna) print(arr[1, 2]) # 7 (segunda fila, tercera columna) # Slicing print(arr[0, :]) # [1, 2, 3, 4] - primera fila completa print(arr[:, 1]) # [2, 6, 10] - segunda columna print(arr[:2, 1:3]) # [[2, 3], [6, 7]] - submatriz # Indexación booleana (filtrado) print(arr[arr > 5]) # [6, 7, 8, 9, 10, 11, 12] # Fancy indexing indices = [0, 2] print(arr[indices]) # Filas 0 y 2
arr.copy().
pandas: Manipulación de Datos
pandas proporciona estructuras de datos de alto nivel y herramientas para el análisis de datos. Sus dos estructuras principales son Series (arrays unidimensionales con índices) y DataFrame (tablas bidimensionales etiquetadas).
Series y DataFrames
import pandas as pd import numpy as np # Crear una Series s = pd.Series([10, 20, 30, 40], index=['a', 'b', 'c', 'd']) print(s['b']) # 20 # Crear un DataFrame desde diccionario data = { 'nombre': ['Ana', 'Luis', 'María', 'Carlos'], 'edad': [25, 30, 28, 35], 'ciudad': ['Lima', 'Bogotá', 'Lima', 'Santiago'], 'salario': [3000, 4500, 3800, 5200] } df = pd.DataFrame(data) print(df)
0 Ana 25 Lima 3000
1 Luis 30 Bogotá 4500
2 María 28 Lima 3800
3 Carlos 35 Santiago 5200
Selección y Filtrado
# Seleccionar columnas print(df['nombre']) # Una columna (Series) print(df[['nombre', 'edad']]) # Múltiples columnas (DataFrame) # Seleccionar filas por índice print(df.loc[0]) # Por etiqueta print(df.iloc[0:2]) # Por posición (slicing) # Filtrado condicional mayores_28 = df[df['edad'] > 28] print(mayores_28) # Múltiples condiciones filtrado = df[(df['edad'] > 25) & (df['salario'] > 4000)] print(filtrado) # Filtrado con isin ciudades_interes = df[df['ciudad'].isin(['Lima', 'Bogotá'])] print(ciudades_interes)
Operaciones de Agregación
# Estadísticas descriptivas print(df.describe()) # Agregaciones por columna print(df['salario'].mean()) # Promedio: 4125.0 print(df['edad'].median()) # Mediana: 29.0 # GroupBy: agrupar y agregar por_ciudad = df.groupby('ciudad')['salario'].mean() print(por_ciudad) # Múltiples agregaciones resumen = df.groupby('ciudad').agg({ 'salario': ['mean', 'max'], 'edad': 'mean' }) print(resumen)
Bogotá 4500.0
Lima 3400.0
Santiago 5200.0
Name: salario, dtype: float64
Limpieza de Datos
import pandas as pd import numpy as np # DataFrame con valores faltantes df = pd.DataFrame({ 'A': [1, 2, np.nan, 4], 'B': [5, np.nan, np.nan, 8], 'C': ['x', 'y', 'z', 'w'] }) # Detectar valores nulos print(df.isnull()) print(df.isnull().sum()) # Conteo por columna # Eliminar filas con NaN df_limpio = df.dropna() # Rellenar valores faltantes df_filled = df.fillna(0) # Con valor fijo df_filled = df.fillna(df.mean()) # Con promedio df_filled = df.fillna(method='ffill') # Forward fill # Eliminar duplicados df_unique = df.drop_duplicates() # Renombrar columnas df = df.rename(columns={'A': 'columna_a'}) # Cambiar tipos de datos df['A'] = df['A'].astype(float)
NaN) es crucial en Data Science. pandas representa los valores faltantes con np.nan para datos numéricos y None o pd.NA para otros tipos.
matplotlib: Visualización de Datos
matplotlib es la biblioteca de visualización más utilizada en Python. Permite crear gráficos estáticos, animados e interactivos de alta calidad, desde simples líneas hasta complejas visualizaciones científicas.
Gráficos Básicos
import matplotlib.pyplot as plt import numpy as np # Datos de ejemplo x = np.linspace(0, 10, 100) y = np.sin(x) # Gráfico de línea plt.figure(figsize=(10, 6)) plt.plot(x, y, label='sin(x)', color='#00ffc8', linewidth=2) plt.plot(x, np.cos(x), label='cos(x)', color='#ff6b9d', linewidth=2) # Personalización plt.title('Funciones Trigonométricas', fontsize=14) plt.xlabel('X') plt.ylabel('Y') plt.legend() plt.grid(True, alpha=0.3) # Guardar y mostrar plt.savefig('trigonometric.png', dpi=150) plt.show()
Tipos de Gráficos
| Función | Tipo | Uso |
|---|---|---|
| plt.plot() | Línea | Series temporales, tendencias |
| plt.scatter() | Dispersión | Correlaciones, distribuciones |
| plt.bar() | Barras | Comparaciones categóricas |
| plt.hist() | Histograma | Distribución de frecuencias |
| plt.pie() | Circular | Proporciones del total |
| plt.boxplot() | Caja | Distribución y outliers |
Múltiples Subplots
import matplotlib.pyplot as plt import numpy as np # Crear figura con subplots fig, axes = plt.subplots(2, 2, figsize=(12, 10)) # Datos x = np.linspace(0, 10, 50) data = np.random.randn(1000) # Subplot 1: Línea axes[0, 0].plot(x, np.sin(x), color='#00ffc8') axes[0, 0].set_title('Gráfico de Línea') # Subplot 2: Dispersión axes[0, 1].scatter(x, np.cos(x) + np.random.randn(50)*0.1, color='#ff6b9d', alpha=0.7) axes[0, 1].set_title('Gráfico de Dispersión') # Subplot 3: Histograma axes[1, 0].hist(data, bins=30, color='#ffd93d', edgecolor='black') axes[1, 0].set_title('Histograma') # Subplot 4: Barras categorias = ['A', 'B', 'C', 'D'] valores = [23, 45, 56, 78] axes[1, 1].bar(categorias, valores, color='#6bcfff') axes[1, 1].set_title('Gráfico de Barras') plt.tight_layout() plt.savefig('subplots.png', dpi=150) plt.show()
Integración con pandas
import pandas as pd import matplotlib.pyplot as plt # pandas integra matplotlib directamente df = pd.DataFrame({ 'mes': ['Ene', 'Feb', 'Mar', 'Abr', 'May'], 'ventas': [100, 150, 200, 180, 220], 'gastos': [80, 90, 120, 110, 130] }) # Gráfico directo desde DataFrame df.plot(x='mes', y=['ventas', 'gastos'], kind='bar', figsize=(10, 6)) plt.title('Ventas vs Gastos por Mes') plt.ylabel('Cantidad ($)') plt.xticks(rotation=0) plt.legend(loc='upper left') plt.show()
seaborn (construido sobre matplotlib) o plotly para gráficos interactivos.
Proyecto: Análisis de Datos Completo
Integremos todo lo aprendido en un flujo de trabajo de Data Science típico: cargar datos, limpiarlos, analizarlos y visualizar los resultados.
Carga y Exploración
import pandas as pd import numpy as np import matplotlib.pyplot as plt # Cargar datos (ejemplo con CSV) # df = pd.read_csv('datos.csv') # Crear datos de ejemplo: ventas de productos np.random.seed(42) n = 200 df = pd.DataFrame({ 'fecha': pd.date_range('2024-01-01', periods=n, freq='D'), 'producto': np.random.choice(['A', 'B', 'C'], n), 'region': np.random.choice(['Norte', 'Sur', 'Este', 'Oeste'], n), 'unidades': np.random.randint(10, 100, n), 'precio': np.random.uniform(15, 50, n).round(2) }) # Agregar valores nulos aleatorios df.loc[np.random.choice(n, 10), 'unidades'] = np.nan # Exploración inicial print("="*50) print("EXPLORACIÓN DE DATOS") print("="*50) print(f"\nDimensiones: {df.shape}") print(f"\nPrimeras filas:\n{df.head()}") print(f"\nTipos de datos:\n{df.dtypes}") print(f"\nValores nulos:\n{df.isnull().sum()}")
Limpieza y Transformación
# Manejar valores faltantes df['unidades'] = df['unidades'].fillna(df['unidades'].median()) # Crear columnas derivadas df['total_venta'] = df['unidades'] * df['precio'] df['mes'] = df['fecha'].dt.month df['dia_semana'] = df['fecha'].dt.day_name() # Categorizar precios df['categoria_precio'] = pd.cut( df['precio'], bins=[0, 25, 35, 50], labels=['Bajo', 'Medio', 'Alto'] ) print("\nDataFrame transformado:\n", df.head())
Análisis y Agregación
print("="*50) print("ANÁLISIS DE DATOS") print("="*50) # Ventas por producto ventas_producto = df.groupby('producto').agg({ 'total_venta': ['sum', 'mean', 'count'], 'unidades': 'sum' }).round(2) print("\nVentas por Producto:\n", ventas_producto) # Ventas por región ventas_region = df.groupby('region')['total_venta'].sum().sort_values(ascending=False) print("\nVentas por Región:\n", ventas_region) # Tendencia mensual tendencia = df.groupby('mes')['total_venta'].sum() print("\nTendencia Mensual:\n", tendencia) # Tabla pivote pivot = pd.pivot_table( df, values='total_venta', index='region', columns='producto', aggfunc='sum' ).round(2) print("\nTabla Pivote (Región x Producto):\n", pivot)
Visualización de Resultados
# Configurar estilo plt.style.use('dark_background') # Crear dashboard fig, axes = plt.subplots(2, 2, figsize=(14, 10)) fig.suptitle('Dashboard de Ventas', fontsize=16, color='#00ffc8') # 1. Ventas por producto (barras) ventas_prod = df.groupby('producto')['total_venta'].sum() axes[0, 0].bar(ventas_prod.index, ventas_prod.values, color=['#00ffc8', '#ff6b9d', '#ffd93d']) axes[0, 0].set_title('Ventas por Producto', color='white') axes[0, 0].set_ylabel('Total Ventas ($)') # 2. Distribución de precios (histograma) axes[0, 1].hist(df['precio'], bins=20, color='#6bcfff', edgecolor='white', alpha=0.8) axes[0, 1].set_title('Distribución de Precios', color='white') axes[0, 1].set_xlabel('Precio ($)') # 3. Tendencia mensual (línea) axes[1, 0].plot(tendencia.index, tendencia.values, marker='o', color='#00ffc8', linewidth=2) axes[1, 0].set_title('Tendencia Mensual', color='white') axes[1, 0].set_xlabel('Mes') axes[1, 0].set_ylabel('Ventas ($)') axes[1, 0].fill_between(tendencia.index, tendencia.values, alpha=0.3, color='#00ffc8') # 4. Ventas por región (pie) ventas_region.plot(kind='pie', ax=axes[1, 1], colors=['#00ffc8', '#ff6b9d', '#ffd93d', '#6bcfff'], autopct='%1.1f%%') axes[1, 1].set_title('Distribución por Región', color='white') axes[1, 1].set_ylabel('') plt.tight_layout() plt.savefig('dashboard_ventas.png', dpi=150, facecolor='#0a0a0f', edgecolor='none') plt.show()
Resumen del Capítulo
01 // IPython & Jupyter
Entornos interactivos para desarrollo exploratorio con comandos mágicos y notebooks ejecutables.
02 // NumPy
Arrays multidimensionales eficientes con operaciones vectorizadas y broadcasting.
03 // pandas
Series y DataFrames para manipulación de datos tabulares con selección, filtrado y agregación.
04 // matplotlib
Visualización de datos con gráficos de línea, barras, dispersión, histogramas y más.