Análisis de Datos con Pandas y Python: Guía Práctica 2026
Tutoriales

Análisis de Datos con Pandas y Python: Guía Práctica 2026

14 min de lectura
105 Vistas
Compartir:

Por qué Pandas es la herramienta de datos más importante de Python

Después de trabajar con datos en diferentes contextos, desde análisis de ventas para startups hasta procesamiento de datos de sensores industriales, puedo decirte que Pandas aparece en casi todos los proyectos de datos en Python. No porque sea perfecta (tiene sus limitaciones), sino porque su balance entre facilidad de uso y potencia es insuperable para datasets de tamaño moderado.

En 2026, Pandas versión 2.x con su backend en Arrow es significativamente más rápido que versiones anteriores. Si tienes experiencia con Pandas 1.x, la sintaxis es compatible pero hay mejoras importantes en rendimiento y en el manejo de tipos de datos.

Instalación y configuración

# Crear entorno virtual (recomendado siempre)
python -m venv env
source env/bin/activate  # Linux/Mac
# env\Scripts\activate   # Windows

# Instalar las librerías necesarias
pip install pandas numpy matplotlib seaborn openpyxl

# Verificar instalación
python -c "import pandas as pd; print(pd.__version__)"

# Para Jupyter (opcional pero recomendado para exploración)
pip install jupyter
jupyter notebook

Estructuras de datos fundamentales

Series: el array unidimensional de Pandas

Una Series es una columna de datos con un índice. Piensa en ella como una lista con etiquetas en cada fila.

import pandas as pd
import numpy as np

# Crear una Serie desde una lista
temperaturas = pd.Series([22, 25, 19, 28, 23], name='temperatura_celsius')
print(temperaturas)
# 0    22
# 1    25
# 2    19
# 3    28
# 4    23

# Con índice personalizado
ventas = pd.Series(
    [1500, 2300, 1800, 2900],
    index=['Ene', 'Feb', 'Mar', 'Abr'],
    name='ventas_USD'
)

# Operaciones vectorizadas (sin bucles)
ventas_con_iva = ventas * 1.18
ventas_en_soles = ventas * 3.7  # Tasa aproximada PEN/USD

# Filtrado
meses_altos = ventas[ventas > 2000]
print(meses_altos)
# Feb    2300
# Abr    2900

DataFrame: la tabla de datos central

# Crear DataFrame desde diccionario
df = pd.DataFrame({
    'nombre': ['Ana García', 'Carlos Pérez', 'María López', 'Juan Torres'],
    'edad': [28, 35, 42, 29],
    'ciudad': ['Lima', 'Bogotá', 'Ciudad de México', 'Santiago'],
    'salario': [3500, 5200, 4800, 3900],
    'activo': [True, True, False, True]
})

# Información básica
print(df.shape)          # (4, 5) — filas x columnas
print(df.dtypes)         # Tipos de cada columna
print(df.describe())     # Estadísticas descriptivas
print(df.info())         # Resumen completo con memoria usada

# Acceso a columnas
print(df['nombre'])      # Serie
print(df[['nombre', 'salario']])  # DataFrame de 2 columnas

# Acceso a filas
print(df.iloc[0])        # Primera fila por posición
print(df.loc[0])         # Primera fila por etiqueta (aquí igual)
print(df.loc[df['ciudad'] == 'Lima'])  # Filtro

Carga de datos desde diferentes fuentes

import pandas as pd

# CSV (el formato más común)
df = pd.read_csv('datos.csv', encoding='utf-8')
df = pd.read_csv('datos.csv', sep=';', decimal=',')  # Formato europeo
df = pd.read_csv('datos.csv', parse_dates=['fecha'], index_col='id')

# Excel
df = pd.read_excel('reporte.xlsx', sheet_name='Ventas 2026')

# Desde URL (muy útil para datasets públicos)
url = 'https://raw.githubusercontent.com/datasets/covid-19/main/data/countries-aggregated.csv'
df_covid = pd.read_csv(url)

# Desde una base de datos (con SQLAlchemy)
from sqlalchemy import create_engine
engine = create_engine('postgresql://usuario:password@localhost/mi_db')
df = pd.read_sql('SELECT * FROM ventas WHERE año = 2026', engine)

# Guardar datos
df.to_csv('resultado.csv', index=False, encoding='utf-8-sig')  # utf-8-sig para Excel en Windows
df.to_excel('resultado.xlsx', index=False, sheet_name='Análisis')

Limpieza y transformación de datos

En mi experiencia, el 70% del tiempo en análisis de datos se va en limpiar y preparar los datos. Pandas tiene herramientas excelentes para esto.

# Detectar valores nulos
print(df.isnull().sum())          # Nulos por columna
print(df.isnull().sum().sum())    # Total de nulos
print(f"% nulos: {df.isnull().mean() * 100}")

# Manejar valores nulos
df_limpio = df.dropna()                          # Eliminar filas con cualquier nulo
df_limpio = df.dropna(subset=['columna_clave'])  # Solo si cierta columna es nula
df['precio'].fillna(df['precio'].median(), inplace=True)  # Rellenar con mediana
df['categoria'].fillna('Sin categoría', inplace=True)

# Tipos de datos
df['fecha'] = pd.to_datetime(df['fecha'], format='%d/%m/%Y')
df['precio'] = pd.to_numeric(df['precio'], errors='coerce')  # NaN si no puede convertir

# Eliminar duplicados
print(df.duplicated().sum())
df = df.drop_duplicates()
df = df.drop_duplicates(subset=['email'])  # Por columna específica

# Normalizar texto
df['nombre'] = df['nombre'].str.strip().str.title()
df['email'] = df['email'].str.lower()

# Renombrar columnas
df = df.rename(columns={
    'Nombre Completo': 'nombre',
    'Fecha Nacimiento': 'fecha_nacimiento',
    'Ciudad Residencia': 'ciudad'
})

# Crear columnas derivadas
df['edad'] = (pd.Timestamp.now() - df['fecha_nacimiento']).dt.days // 365
df['salario_anual'] = df['salario_mensual'] * 12
df['rango_salarial'] = pd.cut(df['salario_mensual'],
    bins=[0, 2000, 4000, 7000, float('inf')],
    labels=['Bajo', 'Medio', 'Alto', 'Muy alto']
)

Agrupación y análisis

# groupby: el corazón del análisis agregado
df_ventas = pd.DataFrame({
    'region': ['Norte', 'Sur', 'Norte', 'Centro', 'Sur', 'Norte', 'Centro'],
    'producto': ['A', 'B', 'A', 'C', 'B', 'C', 'A'],
    'cantidad': [100, 80, 120, 90, 110, 70, 95],
    'precio_unit': [15.5, 22.0, 15.5, 31.0, 22.0, 31.0, 15.5]
})

df_ventas['total'] = df_ventas['cantidad'] * df_ventas['precio_unit']

# Análisis por región
por_region = df_ventas.groupby('region').agg(
    total_ventas=('total', 'sum'),
    promedio_venta=('total', 'mean'),
    num_transacciones=('total', 'count'),
    cantidad_total=('cantidad', 'sum')
).round(2)

print(por_region)

# Tabla pivote
pivot = df_ventas.pivot_table(
    values='total',
    index='region',
    columns='producto',
    aggfunc='sum',
    fill_value=0
)
print(pivot)

Visualización rápida con Pandas y Seaborn

import matplotlib.pyplot as plt
import seaborn as sns

# Configuración de estilo
sns.set_theme(style='whitegrid', palette='muted')
plt.rcParams['figure.figsize'] = [10, 6]

# Visualizaciones directas desde Pandas
df_ventas['total'].plot(kind='hist', bins=15, title='Distribución de Ventas')
plt.savefig('histograma_ventas.png', dpi=150, bbox_inches='tight')
plt.close()

# Gráfico de barras por región
por_region['total_ventas'].sort_values().plot(
    kind='barh',
    title='Ventas Totales por Región',
    xlabel='USD'
)
plt.tight_layout()
plt.savefig('ventas_por_region.png', dpi=150)
plt.close()

# Con Seaborn (más estético)
fig, axes = plt.subplots(1, 2, figsize=(14, 5))
sns.boxplot(data=df_ventas, x='region', y='total', ax=axes[0])
axes[0].set_title('Distribución de ventas por región')
sns.heatmap(pivot, annot=True, fmt='.0f', cmap='Blues', ax=axes[1])
axes[1].set_title('Mapa de calor: Región vs Producto')
plt.tight_layout()
plt.savefig('analisis_completo.png', dpi=150)
plt.close()

Tabla comparativa: operaciones fundamentales

OperaciónPandasEquivalente SQLRendimiento
Filtrar filasdf[df['col'] > valor]WHERE col > valorVectorizado, rápido
Agrupar y agregardf.groupby('col').agg()GROUP BY colMuy rápido
Unir DataFramespd.merge(df1, df2, on='id')JOINEficiente hasta ~10M filas
Ordenardf.sort_values('col')ORDER BY colO(n log n)
Eliminar duplicadosdf.drop_duplicates()SELECT DISTINCTRápido
Pivot tabledf.pivot_table()PIVOT (no estándar)Moderado

Errores comunes y soluciones

SettingWithCopyWarning: A value is trying to be set on a copy of a slice

Este es el error más frecuente en Pandas. Ocurre cuando modificas un DataFrame que es una copia de otro. Solución: usa .loc explícitamente para asignación, por ejemplo df.loc[condicion, 'columna'] = valor, o crea una copia explícita con df_nuevo = df[condicion].copy() antes de modificar.

KeyError: 'nombre_columna'

La columna no existe o tiene espacios invisibles. Verifica con print(df.columns.tolist()) para ver los nombres exactos. Si importaste desde Excel o CSV, los nombres pueden tener espacios al inicio o final. Limpia con df.columns = df.columns.str.strip().

MemoryError al cargar archivos grandes

Para archivos CSV de varios GB, carga solo las columnas necesarias con el parámetro usecols=['col1', 'col2'] y especifica los tipos de datos con dtype={'col': 'int32'} para reducir el uso de memoria. Considera leer en chunks con pd.read_csv(archivo, chunksize=100000).

ValueError: Cannot convert non-finite values (NA or inf) to integer

Al intentar convertir una columna a entero cuando tiene valores nulos. Los enteros no admiten NaN en Pandas clásico. Solución: usa el tipo Int64 (con I mayúscula) que sí admite nulos, o rellena los nulos antes de convertir: df['col'].fillna(0).astype(int).

Fechas importadas como string

Cuando las fechas llegan como texto, las operaciones de fecha no funcionan. Convierte explícitamente: df['fecha'] = pd.to_datetime(df['fecha']). Si el formato es ambiguo, especifícalo: pd.to_datetime(df['fecha'], format='%d/%m/%Y'). El parámetro dayfirst=True ayuda con fechas en formato europeo/latinoamericano.

Optimización del rendimiento en Pandas 2.x

Una de las mejoras más importantes en Pandas 2.x es el soporte para el backend Apache Arrow, que reduce el consumo de memoria entre un 30% y un 70% comparado con versiones anteriores. Para activarlo, usa el tipo ArrowDtype al crear tu DataFrame o usa pd.read_csv(archivo, dtype_backend="pyarrow"). En operaciones sobre datasets de varios cientos de miles de filas, la diferencia es perceptible. Llevo varios meses usando Pandas 2.x en producción y la mejora en velocidad de filtros y agrupaciones es consistente, especialmente con columnas de texto y categorías.

Para datasets que no caben en RAM, la librería Dask extiende la API de Pandas para procesamiento distribuido. Su sintaxis es casi idéntica, por lo que la curva de aprendizaje es mínima si ya conoces Pandas.

Recursos adicionales

J
Escrito por
Jesús García

Apasionado por la tecnologia y las finanzas personales. Escribo sobre innovacion, inteligencia artificial, inversiones y estrategias para mejorar tu economia. Mi objetivo es hacer que temas complejos sean accesibles para todos.

Compartir artículo:

Artículos relacionados

Comentarios

Deja un comentario

Herramientas Recomendadas

Las que usamos en nuestros proyectos

Enlaces de afiliado. Sin costo adicional para ti.

¿Necesitas servicios de tecnología?

Ofrecemos soluciones integrales de desarrollo web, aplicaciones móviles, consultoría y más.

Desarrollo Web Apps Móviles Consultoría