Skip to content
Empieza gratis

¿Por qué no aparece un mes sin ventas al agrupar?

Un mes sin ventas no sale con 0: no sale. Un calendario lo hace aparecer, y tú decides qué valor lleva.

Curso gratis. Tu Maestro, una IA, .

Agosto en Coyoacán

La sucursal de Coyoacán cerró todo agosto de 2025 por remodelación. En ventas_diarias no hay ninguna fila de Coyoacán en agosto: nadie registró ventas en 0, simplemente no hay filas. Además, las tres sucursales cierran el 1 de enero y el 25 de diciembre.

La dirección pregunta cuánto vende Coyoacán al mes, en promedio, en 2025. Predice qué pasa con un caso chico.

Una sucursal que abrió julio y septiembre, y cerró agosto, con 1,000 pesos de venta cada día abierto. Escribe qué crees que imprime y por qué.

Una sucursal que abrió julio y septiembre, y cerró agosto, con 1,000 pesos de venta cada día abierto. Escribe qué crees que imprime y por qué.

Ventas por mes y promedio

promedio.py
import pandas as pd

dias = pd.date_range("2025-07-01", "2025-09-30", freq="D")
dias = dias[dias.month != 8]  # la sucursal cerró agosto
ventas = pd.DataFrame({"fecha": dias, "ventas": 1000})

por_mes = ventas.groupby(ventas["fecha"].dt.to_period("M"))["ventas"].sum()
print(por_mes)
print("promedio mensual:", por_mes.mean())

Adivinar está bien: se guarda tal como la escribiste para compararla. Solo tú y tu Maestro ven tus predicciones.

Haz tu predicción

Lo que la tabla no dice

Un mes sin filas no es un mes con 0. Es un mes que no existe para GROUP BY. Con Coyoacán en 2025 pasa a lo grande: salen 11 meses que suman 4,017,120 pesos. El promedio de esos 11 meses es 365,193 pesos. Dividido entre los 12 meses del año es 334,760.

¿Cuál es el bueno? Depende de la pregunta, y esa decisión es tuya, no de las filas que faltan:

  • Si preguntan cuánto dejó la sucursal al mes en 2025, agosto cuenta con 0 y el promedio es 334,760.
  • Si preguntan cuánto vende un mes en que está abierta, agosto no cuenta y el promedio es 365,193. Pero entonces dilo en el reporte.

Con los días pasa lo mismo: en 2025, Roma y Del Valle tienen 363 filas, no 365, y Coyoacán tiene 332. Si no sabes cuál promedio usar en tu caso, platícalo con tu Maestro.

Un calendario

Para que el mes aparezca necesitas una tabla con todos los periodos, haya ventas o no: un calendario. Después pegas tus datos al calendario y pones 0 donde no hay nada. La gráfica de abajo muestra por qué importa: sin calendario, la línea de Coyoacán une julio con septiembre y el cierre de agosto no se ve.

Inténtalo

El código arma las ventas mensuales de Coyoacán y las dibuja. Agrega un calendario con pd.date_range("2025-01-01", "2026-06-01", freq="MS") (el primer día de cada mes) y usa reindex con fill_value=0 para que agosto aparezca. Ya quedó cuando la línea baja a 0 en agosto de 2025. Si reindex te deja todo en 0, pregúntale a tu Maestro.

Agrega un calendario con todos los meses de enero de 2025 a junio de 2026 y rellena con 0 los que no tienen ventas, para que la línea muestre el cierre de agosto.

Tu turno

Agrega un calendario con todos los meses de enero de 2025 a junio de 2026 y rellena con 0 los que no tienen ventas, para que la línea muestre el cierre de agosto.

La gráfica se vuelve a dibujar cuando haces una pausa, o al momento con Ejecutar.

Listo para ejecutar tu código.

Datos: ventas-diarias, 1,598 filas

Enter guarda una celda y Escape la deja como estaba. Deja una celda vacía para un valor faltante.

Los datos del ejercicio, "ventas-diarias". Tus cambios corren con tu código.
FilaQuitar
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Página 1 de 80

Ejecútalo tú

El calendario es pd.date_range y el pegado es reindex:

Python
calendario = pd.date_range("2025-01-01", "2025-12-01", freq="MS")
por_mes = por_mes.reindex(calendario, fill_value=0)

Ojo: resample("MS").sum() sobre una serie con índice de fechas también crea los meses vacíos, pero solo entre el primero y el último que tienen datos. Un mes vacío al principio o al final no aparece.

El calendario sale de generate_series, y el pegado es un LEFT JOIN desde el calendario, para que se queden todos sus meses:

SQL
WITH calendario AS (
  SELECT mes::DATE AS mes
  FROM generate_series(DATE '2025-01-01', DATE '2025-12-01', INTERVAL 1 MONTH) AS t(mes)
)
SELECT c.mes, coalesce(p.ventas, 0) AS ventas
FROM calendario c
LEFT JOIN por_mes p ON p.mes = c.mes;

coalesce pone 0 donde el LEFT JOIN no encontró ventas.

Inténtalo en DuckDB

La consulta ya tiene el calendario de 2025 y las ventas mensuales de Coyoacán, cada uno en su WITH. Te falta pegarlos: cambia el SELECT final para que salgan los 12 meses, con 0 en agosto. Una buena respuesta tiene 12 filas, de 2025-01-01 a 2025-12-01, y agosto en 0.

Une el calendario de 2025 con las ventas mensuales de Coyoacán para que salgan los 12 meses, con ventas 0 donde no hubo filas.

Tu turno

Une el calendario de 2025 con las ventas mensuales de Coyoacán para que salgan los 12 meses, con ventas 0 donde no hubo filas.

Tablas: ventas_diarias (fecha, sucursal, ventas)

ventas_diarias · 1,598 filas

ColumnaTipo
fecha El día de la venta.DATE
sucursal Roma, Coyoacán o Del Valle.VARCHAR
ventas Ventas del día en pesos.BIGINT

Primeras filas

fechasucursalventas
2025-01-02Roma12120
2025-01-02Coyoacán10650
2025-01-02Del Valle8880

Cada ejecución empieza con copias nuevas de las tablas del curso, así que puedes probar lo que quieras.

Listo para ejecutar tu consulta.

Ejecútalo tú

Comprueba lo que sabes: Sin calendario, el promedio mensual de Coyoacán en 2025 sale en 365,193 pesos. Con agosto en 0, sale en 334,760. ¿Por qué el primero es más alto?

Si después quieres comparar cada mes con el anterior, un mes que falta también rompe esa cuenta: comparar contra la fila anterior no es comparar contra el mes anterior. El curso gratuito de funciones de ventana lo trata en su página sobre meses que faltan.