Crear un resumen mensual con groupby de pandas y comprobar los totales
Resume datos CSV a nivel de pedido por mes con pandas y después concilia los recuentos, unidades e importes agrupados con la fuente. Un pequeño ejemplo sintético permite verificar manualmente todos los resultados esperados.
Contenido revisado 2026.09.20Incluye archivos de ejemplo
Ver el índice
La traducción se ha realizado con IA. Comprueba el código, las unidades y los valores junto con el original. La revisión por hablantes nativos de cada idioma aún no se ha completado. English
Para quién esEsta guía está dirigida a personas que necesitan un resumen CSV mensual repetible y quieren comprobaciones explícitas de que la agregación no perdió registros.
Preparación
Python 3.12 y un comando de terminal que inicie esa versión.
pandas instalado con python -m pip install pandas.
Una carpeta de trabajo donde el script pueda crear una nueva carpeta dentro de outputs.
El CSV de origen debe contener las columnas order_id, order_date, units y amount.
01Definir las medidas mensuales
Este ejemplo genera una fila por calendar month con tres medidas: order count, total units y total amount. La fuente sintética utiliza una fila por order, por lo que contar filas equivale a contar orders en este dataset concreto.
El paso importante es la reconciliation. Después de groupby, los valores mensuales se vuelven a sumar y se comparan con los source totals. Un summary puede parecer razonable incluso cuando algunas rows se filtraron, duplicaron o eliminaron accidentalmente.
02Crear el CSV sintético
El dataset siguiente es sintético y fue creado específicamente para este artículo. Guárdalo como monthly_orders.csv. Contiene siete orders entre enero, febrero y marzo de 2026.
Los source totals son lo bastante sencillos como para comprobarlos manualmente. Hay 7 orders. Units suman 18: 2 + 3 + 1 + 4 + 2 + 5 + 1. Amount suma 430: 40 + 60 + 25 + 100 + 50 + 125 + 30.
Medida
Total de origen
Orders
7
Units
18
Amount
430
03Calcular manualmente las filas mensuales esperadas
Enero contiene O001 y O002. Febrero contiene O003, O004 y O005. Marzo contiene O006 y O007. Al sumar cada group se obtiene la tabla mensual esperada.
month
orders
units
amount
2026-01
2
5
100
2026-02
3
7
175
2026-03
2
6
155
Los monthly totals concilian con la fuente: 2 + 3 + 2 = 7 orders, 5 + 7 + 6 = 18 units y 100 + 175 + 155 = 430 amount.
04Crear y verificar el resumen con pandas
Guarda el script siguiente como monthly_summary_pandas.py. Valida las required columns, rechaza order IDs ausentes o duplicados, interpreta las fechas con un único formato explícito, convierte las numeric columns, agrupa por month, concilia los totals y escribe el resultado únicamente después de superar esas comprobaciones.
python
from pathlib import Path
import pandas as pd
SOURCE = Path("monthly_orders.csv")
OUTPUT_DIR = Path("outputs") / "monthly_summary_result"
OUTPUT = OUTPUT_DIR / "monthly_summary.csv"
REQUIRED = ["order_id", "order_date", "units", "amount"]
def main() -> None:
if not SOURCE.is_file():
raise FileNotFoundError(f"Source CSV not found: {SOURCE}")
if OUTPUT_DIR.exists():
raise FileExistsError(f"Output folder already exists: {OUTPUT_DIR}")
data = pd.read_csv(SOURCE, dtype={"order_id": "string"})
missing = [name for name in REQUIRED if name not in data.columns]
if missing:
raise ValueError(f"Missing required columns: {missing}")
if data.empty:
raise ValueError("Source CSV contains no data rows.")
if data[REQUIRED].isna().any().any():
raise ValueError("A required field contains a missing value.")
if data["order_id"].str.strip().eq("").any():
raise ValueError("order_id contains a blank value.")
if data["order_id"].duplicated().any():
raise ValueError("Duplicate order_id found.")
data["order_date"] = pd.to_datetime(
data["order_date"], format="%Y-%m-%d", errors="raise"
)
data["units"] = pd.to_numeric(data["units"], errors="raise")
data["amount"] = pd.to_numeric(data["amount"], errors="raise")
data["month"] = data["order_date"].dt.to_period("M").astype(str)
summary = (
data.groupby("month", as_index=False, sort=True)
.agg(
orders=("order_id", "count"),
units=("units", "sum"),
amount=("amount", "sum"),
)
)
source_totals = (len(data), data["units"].sum(), data["amount"].sum())
summary_totals = (
summary["orders"].sum(),
summary["units"].sum(),
summary["amount"].sum(),
)
if summary_totals != source_totals:
raise RuntimeError("Monthly totals do not reconcile with the source.")
OUTPUT_DIR.parent.mkdir(parents=True, exist_ok=True)
OUTPUT_DIR.mkdir()
summary.to_csv(OUTPUT, index=False)
check = pd.read_csv(OUTPUT)
if check.to_dict("records") != summary.to_dict("records"):
raise RuntimeError("Saved CSV does not match the calculated summary.")
print(f"Source rows: {len(data)}.")
print(f"Months: {len(summary)}.")
print(f"Verified totals: units={source_totals[1]}, amount={source_totals[2]}.")
print(f"Output: {OUTPUT.as_posix()}")
if __name__ == "__main__":
main()
text
python monthly_summary_pandas.py
05Comparar la salida esperada
La salida debería contener tres data rows ordenadas por month. El contenido esperado del CSV se muestra a continuación.
La salida de consola esperada que aparece a continuación se obtuvo manualmente a partir de los datos sintéticos y del código. No es un execution log capturado.
06Conciliar el resultado y reconocer errores comunes
Cuenta las source rows: 7.
Suma los monthly orders: 2 + 3 + 2 = 7.
Suma las monthly units: 5 + 7 + 6 = 18.
Suma el monthly amount: 100 + 175 + 155 = 430.
Confirma que la salida contenga exactamente 2026-01, 2026-02 y 2026-03.
Ejecuta el script de nuevo sin cambiar OUTPUT_DIR. Debería detenerse con FileExistsError en lugar de sustituir el resultado existente.
Síntoma
Qué comprobar
ModuleNotFoundError for pandas
Instala pandas en el mismo Python environment con python -m pip install pandas.
Missing required columns
Comprueba el CSV header antes de cambiar el expected schema.
Date parsing error
Confirma que cada order_date utilice YYYY-MM-DD.
Numeric conversion error
Inspecciona units y amount para detectar text, currency symbols o separators que requieran una cleanup rule explícita.
Duplicate order_id found
Determina si el ID repetido es un accidental duplicate o representa un data model diferente.
FileExistsError
Revisa el resultado anterior y utiliza una output folder nueva en lugar de sobrescribirlo.
Que coincidan los grand totals no demuestra que todos los months sean correctos, porque dos errores mensuales pueden compensarse entre sí. Para reports importantes, inspecciona también varias source rows conocidas y month-level subtotals.
07Comprender los límites
El ejemplo supone una fila por order e importes enteros. Si un order ocupa varias line-item rows, utiliza una rule como order_id.nunique() en lugar de row count. Los monetary data reales también pueden necesitar fixed-point integer units o procesamiento basado en Decimal en lugar de ordinary floating-point arithmetic.
Month se deriva directamente de una date sin time-zone handling. Si los datos reales contienen timestamps de varias zones, define la business time zone antes de agrupar. Refunds, cancellations, filters y missing records también necesitan business rules explícitas; la arithmetic reconciliation por sí sola no puede determinar si esas rows deben incluirse en el report.
Registro de ejecución y verificación
2026-09-20 · ejemplo revisado manualmente · objetivo: Python 3.12 · se requiere pandas · sin ejecución
Se contaron manualmente 7 source records entre enero, febrero y marzo de 2026.
Se calcularon manualmente source totals de 18 units y 430 amount.
Se calculó manualmente enero como 2 orders, 5 units, 100 amount; febrero como 3 orders, 7 units, 175 amount; y marzo como 2 orders, 6 units, 155 amount.
Se conciliaron manualmente los monthly totals de nuevo con 7 orders, 18 units y 430 amount.
Se revisó el script para required-column checks, duplicate IDs, explicit date parsing, numeric conversion, groupby aggregation, reconciliation, saved-file comparison y output collision protection.
Se obtuvieron manualmente el CSV esperado y la salida de consola.
Límites de la verificación
El código no fue ejecutado por el autor de esta respuesta; aquí no se probaron el comportamiento de pandas ni las filesystem writes.
No se probaron Decimal currency, time zones, refunds, cancellations, line-item order data ni very large files.
Las URL de la documentación oficial se proporcionaron a partir de ubicaciones de documentación conocidas, pero no se comprobaron en línea.
Las explicaciones y los ejemplos son de elaboración propia. Puedes consultar los comportamientos y conceptos relacionados en las siguientes fuentes oficiales.
Encuentra filas con coincidencia exacta en las cuatro columnas y recopílalas en un nuevo archivo de Excel junto con sus números de fila originales. Revisa cada grupo de duplicados, incluida su primera aparición.
Valida las fechas y las horas de trabajo de un CSV y después guarda los recuentos mensuales de registros y las horas totales como un CSV y un gráfico de barras.
Antes de convertir una tabla en texto, alinea el objeto, el periodo, el denominador y la unidad. Usa una tabla sintética de resultados mensuales para comprobar un valor que cambió de 80 % a 82 % y una conversión de unidades, y después crea una lista de comprobación reutilizable.
Combina hojas de cálculo que utilizan las mismas columnas en una única tabla de Excel, registrando de qué hoja procede cada fila. Un pequeño libro sintético permite verificar manualmente el orden de las filas, los recuentos y los totales.