Hoja de referencia de pandas (Python)
40 elementos esenciales con sintaxis y ejemplos. Busca o filtra por grupo.
read_csv
Carga un archivo CSV en un DataFrame. Los demás ejemplos asumen: import pandas as pd; df = pd.read_csv("sales_flat.csv").
pd.read_csv(path, sep=',', usecols=None, dtype=None)import pandas as pd
df = pd.read_csv("sales_flat.csv")
print(df.shape)read_csv(parse_dates=)
Convierte columnas de fecha a datetime al leer, para que .dt y resample funcionen de inmediato.
pd.read_csv(path, parse_dates=["col"])orders = pd.read_csv("orders.csv", parse_dates=["order_date"])
print(orders["order_date"].dtype)read_sql
Ejecuta una consulta SQL y devuelve el resultado como DataFrame.
pd.read_sql(query, connection)import sqlite3
con = sqlite3.connect("sunshine_grocers.db")
stores = pd.read_sql("SELECT * FROM stores WHERE region = 'South'", con)
con.close()to_csv
Guarda un DataFrame en CSV. index=False evita escribir el índice de filas como columna extra.
df.to_csv(path, index=False)df[df["region"] == "South"].to_csv("south_sales.csv", index=False)to_excel
Escribe en un archivo .xlsx (requiere openpyxl). Usa pd.ExcelWriter para escribir varias hojas en un mismo archivo.
df.to_excel(path, sheet_name='Sheet1', index=False)by_region = df.groupby("region", as_index=False)["net_sales"].sum()
by_cat = df.groupby("category", as_index=False)["net_sales"].sum()
with pd.ExcelWriter("summary.xlsx") as writer:
by_region.to_excel(writer, sheet_name="Region", index=False)
by_cat.to_excel(writer, sheet_name="Category", index=False)head / tail / shape
Primeras o últimas n filas (5 por defecto) y el tamaño (filas, columnas).
df.head(n) | df.tail(n) | df.shapeprint(df.head(3))
print(df.shape)info / dtypes
Nombres de columnas, tipos de datos y cantidad de valores no nulos. La primera revisión después de cargar datos.
df.info() | df.dtypesdf.info()
print(df.dtypes)describe
Estadísticas resumidas (conteo, media, desviación, mínimo, cuartiles, máximo) de las columnas numéricas.
df.describe(include=None)print(df[["quantity", "unit_price", "net_sales"]].describe().round(2))value_counts
Cuenta cada valor distinto de una columna; normalize=True devuelve proporciones.
s.value_counts(normalize=False)print(df["channel"].value_counts())
print(df["segment"].value_counts(normalize=True).round(3))Select columns
Una columna devuelve una Serie; una lista de columnas devuelve un DataFrame.
df["col"] | df[["col1", "col2"]]sales = df["net_sales"]
subset = df[["order_date", "store_name", "net_sales"]]loc
Selecciona por etiquetas y condiciones booleanas. También es la forma segura de asignar valores a un subconjunto filtrado.
df.loc[row_condition, columns]south = df.loc[df["region"] == "South", ["store_name", "net_sales"]]
df.loc[df["discount"] > 0, "promo"] = "Yes"iloc
Selecciona por posición entera (empieza en 0 y excluye el final).
df.iloc[rows, cols]first_rows = df.iloc[:5, :4]
last_row = df.iloc[-1]Boolean filter
Filtra filas con condiciones. Pon cada condición entre paréntesis y usa &, |, ~ (no and/or).
df[(cond1) & (cond2)] | | for OR | ~ for NOTbig_online = df[(df["channel"] == "Online") & (df["net_sales"] > 30)]
print(len(big_online))isin
Conserva las filas cuyo valor está en una lista (como IN en SQL).
df[df["col"].isin([v1, v2])]fresh = df[df["category"].isin(["Produce", "Dairy", "Bakery"])]query
Filtra con una expresión de texto fácil de leer. Usa @var para referirte a variables de Python.
df.query("expression")min_sales = 25
result = df.query("region == 'West' and net_sales > @min_sales")between
TRUE cuando el valor está dentro de un rango (inclusivo por defecto). También sirve con fechas en texto ISO.
s.between(left, right, inclusive='both')jan_2025 = df[df["order_date"].between("2025-01-01", "2025-01-31")]New column / assign
Crea columnas calculadas con operaciones vectorizadas. assign devuelve un DataFrame nuevo, útil para encadenar.
df["new"] = expr | df.assign(new=expr)df["profit"] = df["net_sales"] - df["cost"]
df = df.assign(margin_pct=lambda d: d["profit"] / d["net_sales"] * 100)rename
Renombra columnas (o etiquetas del índice) y devuelve un DataFrame nuevo.
df.rename(columns={"old": "new"})out = df.rename(columns={"net_sales": "Net Sales", "store_name": "Store"})sort_values
Ordena las filas por una o varias columnas.
df.sort_values(by, ascending=True)top = df.sort_values(["net_sales", "order_date"], ascending=[False, True]).head(10)drop / drop_duplicates
Elimina columnas, o elimina filas repetidas (todas las columnas o un subconjunto).
df.drop(columns=[...]) | df.drop_duplicates(subset=None, keep='first')dirty = pd.read_csv("sales_dirty.csv")
clean = dirty.drop_duplicates()
print(len(dirty) - len(clean), "duplicates removed")
slim = clean.drop(columns=["brand", "cost"])str methods
Limpieza de texto vectorizada sobre una columna.
s.str.strip() | .str.title() | .str.upper() | .str.replace() | .str.contains()dirty = pd.read_csv("sales_dirty.csv")
dirty["store_name"] = dirty["store_name"].str.strip().str.title()
dirty["category"] = dirty["category"].str.title()to_numeric / astype
Convierte texto en números; errors='coerce' convierte los valores inválidos en NaN. astype cambia el tipo de una columna.
pd.to_numeric(s, errors='coerce') | s.astype(type)dirty = pd.read_csv("sales_dirty.csv")
dirty["net_sales"] = pd.to_numeric(dirty["net_sales"].str.replace("$", "", regex=False))
dirty["quantity"] = dirty["quantity"].str.extract(r"(\d+)", expand=False).astype(int)apply
Aplica una función a cada valor (Serie) o a cada fila (axis=1). Flexible, pero más lenta que el código vectorizado.
s.apply(func) | df.apply(func, axis=1)def size_band(x):
return "Large" if x >= 30 else "Small"
df["basket"] = df["net_sales"].apply(size_band)
print(df["basket"].value_counts())where (numpy)
IF vectorizado y rápido para crear una columna a partir de una condición.
np.where(condition, value_if_true, value_if_false)import numpy as np
df["is_promo"] = np.where(df["discount"] > 0, "Promo", "Regular")isna / notna
Detecta valores faltantes; .sum() da el conteo por columna.
df.isna().sum() | s.notna()dirty = pd.read_csv("sales_dirty.csv")
print(dirty.isna().sum())fillna
Reemplaza valores faltantes. Asigna el resultado de nuevo (inplace en una sola columna no funciona con copy-on-write en pandas 3).
s.fillna(value) | df.fillna({"col": value})dirty = pd.read_csv("sales_dirty.csv")
dirty["region"] = dirty["region"].fillna("Unknown")dropna
Elimina filas con valores faltantes (opcionalmente solo en algunas columnas).
df.dropna(subset=None, how='any')dirty = pd.read_csv("sales_dirty.csv")
with_region = dirty.dropna(subset=["region"])groupby + sum
Divide las filas en grupos y agrega cada uno. as_index=False devuelve un DataFrame normal.
df.groupby(keys)[col].sum()by_region = (df.groupby("region", as_index=False)["net_sales"].sum()
.sort_values("net_sales", ascending=False))
print(by_region)groupby + agg (named)
Varias agregaciones a la vez con nombres de salida claros.
df.groupby(key).agg(new=("col", "func"), ...)summary = df.groupby("store_name").agg(
sales=("net_sales", "sum"),
orders=("order_id", "nunique"),
avg_line=("net_sales", "mean"),
).round(2)
print(summary.head())groupby + transform
Devuelve el resultado del grupo alineado con cada fila original, por ejemplo la participación de cada línea en su región.
df.groupby(key)[col].transform(func)df["region_total"] = df.groupby("region")["net_sales"].transform("sum")
df["pct_of_region"] = df["net_sales"] / df["region_total"] * 100nlargest / nsmallest
Los n valores más altos o más bajos sin ordenar todo el conjunto de datos.
s.nlargest(n) | df.nlargest(n, col)top5 = df.groupby("product_name")["net_sales"].sum().nlargest(5)
print(top5)merge
Une dos DataFrames por columnas clave (como JOIN en SQL). Usa validate= para detectar duplicados inesperados.
pd.merge(left, right, on=key, how='inner'|'left'|'right'|'outer')orders = pd.read_csv("orders.csv")
stores = pd.read_csv("stores.csv")
m = orders.merge(stores[["store_id", "store_name", "region"]],
on="store_id", how="left", validate="many_to_one")concat
Apila DataFrames verticalmente (o lado a lado con axis=1).
pd.concat([df1, df2], ignore_index=True)y2024 = df[df["order_date"] < "2025-01-01"]
y2025 = df[df["order_date"] >= "2025-01-01"]
all_years = pd.concat([y2024, y2025], ignore_index=True)pivot_table
Crea una tabla dinámica estilo Excel.
df.pivot_table(index, columns, values, aggfunc='sum', fill_value=0, margins=False)pt = df.pivot_table(index="region", columns="category",
values="net_sales", aggfunc="sum",
fill_value=0, margins=True).round(0)
print(pt)melt
Convierte columnas anchas en filas largas (lo opuesto a pivot).
df.melt(id_vars, value_vars, var_name, value_name)budget = pd.read_csv("budget.csv")
long = budget.melt(id_vars=["month", "store_id"],
value_vars=["revenue_budget", "expense_budget"],
var_name="type", value_name="amount")crosstab
Tabla de frecuencias de dos columnas. normalize='index' da porcentajes por fila.
pd.crosstab(index, columns, normalize=False)print(pd.crosstab(df["segment"], df["channel"], normalize="index").round(3))to_datetime
Convierte texto en fecha y hora. format='mixed' maneja columnas con varios formatos de fecha.
pd.to_datetime(s, format=None, errors='raise')df["order_date"] = pd.to_datetime(df["order_date"])
dirty = pd.read_csv("sales_dirty.csv")
dirty["order_date"] = pd.to_datetime(dirty["order_date"], format="mixed").dt accessor
Extrae partes de valores de fecha y hora.
s.dt.year | .dt.month | .dt.day_name() | .dt.to_period('M')df["order_date"] = pd.to_datetime(df["order_date"])
df["year"] = df["order_date"].dt.year
df["weekday"] = df["order_date"].dt.day_name()
df["month"] = df["order_date"].dt.to_period("M")resample
Agrupa una serie de tiempo por período: 'D' día, 'W' semana, 'MS' inicio de mes, 'QS' inicio de trimestre, 'YS' inicio de año.
df.resample(rule, on=date_col).agg(...)df["order_date"] = pd.to_datetime(df["order_date"])
monthly = df.resample("MS", on="order_date")["net_sales"].sum()
print(monthly.head())rolling / pct_change
Ventanas móviles (por ejemplo promedio de 3 meses) y crecimiento contra el período anterior.
s.rolling(window).mean() | s.pct_change()df["order_date"] = pd.to_datetime(df["order_date"])
monthly = df.resample("MS", on="order_date")["net_sales"].sum()
trend = pd.DataFrame({
"sales": monthly,
"ma_3m": monthly.rolling(3).mean(),
"mom_pct": monthly.pct_change() * 100,
}).round(1)