La solicitud

De Catherine Hale, Directora General
Tu objetivo
Paso 1 de 4. Construye los ingresos diarios (cada día del calendario) y su suma móvil de 7 días (el día y los 6 días anteriores), calculada sobre todo el historial. Asigna a result un DataFrame con los 3 días de 2025 con la suma móvil de 7 días más alta: columnas order_date (el último día de la ventana), weekday (su nombre de día en inglés, p. ej. 'Thursday') y revenue_7d (redondeada a 2), ordenado por revenue_7d descendente, con el índice reiniciado.
- Usa el DataFrame
orderspendiente - Usa el DataFrame
order_itemspendiente - Muestra exactamente
order_dateweekdayrevenue_7dpendiente
Paso 2 de 4. Calcula los ingresos por mes del calendario de cada año (2023, 2024, 2025), y luego la media de los tres años para cada mes del año. Asigna a result un DataFrame con las columnas month (el nombre del mes en inglés, p. ej. 'January') y avg_revenue (redondeada a 2), 12 filas en orden de calendario de January a December, con el índice reiniciado.
- Usa el DataFrame
orderspendiente - Usa el DataFrame
order_itemspendiente - Muestra exactamente
monthavg_revenuependiente
Paso 3 de 4. Construye los ingresos mensuales (meses etiquetados con su primer día) sobre todo el historial y su cambio interanual en porcentaje (pct_change(12) por 100, redondeado a 1). Asigna a result un DataFrame de octubre, noviembre y diciembre de 2025 con las columnas month (texto 'YYYY-MM', p. ej. '2025-10'), short (el mes de 3 letras, p. ej. 'Oct'), revenue (redondeada a 2) y yoy_pct, ordenado por month ascendente, con el índice reiniciado.
- Usa el DataFrame
orderspendiente - Usa el DataFrame
order_itemspendiente - Muestra exactamente
monthshortrevenueyoy_pctpendiente
Paso 4 de 4. Asigna a result un DataFrame con las columnas year, quarter (1 a 4), revenue (suma de ese trimestre, redondeada a 2) y share_of_year (los ingresos del trimestre divididos entre el total de ese año, redondeado a 3), 12 filas ordenadas por year y luego por quarter ascendente, con el índice reiniciado.
- Usa el DataFrame
orderspendiente - Usa el DataFrame
order_itemspendiente - Muestra exactamente
yearquarterrevenueshare_of_yearpendiente
Paso 1 · tu código
Cargando el editor…
Solución de referencia
| order_id | customer_id | order_date | status | channel |
|---|---|---|---|---|
| 1001 | 125 | 2023-01-01 20:51:19 | completed | web |
| 1002 | 156 | 2023-01-02 07:58:46 | completed | web |
| 1003 | 22 | 2023-01-02 10:25:27 | completed | marketplace |
| 1004 | 48 | 2023-01-02 11:21:51 | completed | marketplace |
Mote revisa tu resultado
Presiona Ejecutar. Cada fila que cumple el objetivo se vuelve una luciérnaga en tu linterna.
Paso 2 · tu código
Cargando el editor…
Solución de referencia
| order_id | customer_id | order_date | status | channel |
|---|---|---|---|---|
| 1001 | 125 | 2023-01-01 20:51:19 | completed | web |
| 1002 | 156 | 2023-01-02 07:58:46 | completed | web |
| 1003 | 22 | 2023-01-02 10:25:27 | completed | marketplace |
| 1004 | 48 | 2023-01-02 11:21:51 | completed | marketplace |
Mote revisa tu resultado
Presiona Ejecutar. Cada fila que cumple el objetivo se vuelve una luciérnaga en tu linterna.
Paso 3 · tu código
Cargando el editor…
Solución de referencia
| order_id | customer_id | order_date | status | channel |
|---|---|---|---|---|
| 1001 | 125 | 2023-01-01 20:51:19 | completed | web |
| 1002 | 156 | 2023-01-02 07:58:46 | completed | web |
| 1003 | 22 | 2023-01-02 10:25:27 | completed | marketplace |
| 1004 | 48 | 2023-01-02 11:21:51 | completed | marketplace |
Mote revisa tu resultado
Presiona Ejecutar. Cada fila que cumple el objetivo se vuelve una luciérnaga en tu linterna.
Paso 4 · tu código
Cargando el editor…
Solución de referencia
| order_id | customer_id | order_date | status | channel |
|---|---|---|---|---|
| 1001 | 125 | 2023-01-01 20:51:19 | completed | web |
| 1002 | 156 | 2023-01-02 07:58:46 | completed | web |
| 1003 | 22 | 2023-01-02 10:25:27 | completed | marketplace |
| 1004 | 48 | 2023-01-02 11:21:51 | completed | marketplace |
Mote revisa tu resultado
Presiona Ejecutar. Cada fila que cumple el objetivo se vuelve una luciérnaga en tu linterna.
Lo que recibe Catherine, y por qué
DataFrames
Cargados como DataFrames de pandas, junto con pd y np.
orders12,000 filas · 7 columnas
order_idintegercustomer_idintegerorder_datetimestampstatusvarcharchannelvarcharshipping_feedecimalcoupon_codevarchar
| order_id | customer_id | order_date | status | channel | shipping_fee | coupon_code |
|---|---|---|---|---|---|---|
| 1001 | 125 | 2023-01-01 20:51:19 | completed | web | 0.00 | NaN |
| 1002 | 156 | 2023-01-02 07:58:46 | completed | web | 0.00 | NaN |
| 1003 | 22 | 2023-01-02 10:25:27 | completed | marketplace | 4.99 | WELCOME10 |
| 1004 | 48 | 2023-01-02 11:21:51 | completed | marketplace | 4.99 | WELCOME10 |
| 1005 | 82 | 2023-01-02 11:43:36 | completed | web | 0.00 | WELCOME10 |
order_items30,338 filas · 6 columnas
order_item_idintegerorder_idintegerproduct_idintegerquantityintegerunit_pricedecimaldiscount_pctdecimal
| order_item_id | order_id | product_id | quantity | unit_price | discount_pct |
|---|---|---|---|---|---|
| 1 | 1001 | 121 | 9 | 31.99 | 0.00 |
| 2 | 1001 | 154 | 3 | 11.99 | 0.00 |
| 3 | 1002 | 154 | 4 | 11.99 | 0.00 |
| 4 | 1002 | 194 | 1 | 149.00 | 0.00 |
| 5 | 1002 | 193 | 2 | 19.99 | 0.00 |
customers2,018 filas · 9 columnas
customer_idintegerfirst_namevarcharlast_namevarcharemailvarcharcityvarcharstatevarcharsignup_datedatesegmentvarcharreferral_sourcevarchar
| customer_id | first_name | last_name | city | state | signup_date | segment | referral_source | |
|---|---|---|---|---|---|---|---|---|
| 1 | Owen | Hudson | owen.hudson@icloud.com | San Francisco | CA | 2022-06-02 | consumer | search |
| 2 | Douglas | Mendoza | dmendoza69@gmail.com | Atlanta | GA | 2022-06-02 | consumer | NaN |
| 3 | Henry | Brooks | hbrooks@lakesidecafe.com | Los Angeles | CA | 2022-06-04 | business | NaN |
| 4 | Brian | Graham | bgraham@bluecedarhomes.com | Seattle | WA | 2022-06-06 | business | |
| 5 | Kyle | Jimenez | kjimenez27@yahoo.com | Indianapolis | IN | 2022-06-07 | consumer | NaN |
products120 filas · 8 columnas
product_idintegernamevarcharcategoryvarcharsubcategoryvarcharunit_pricedecimalunit_costdecimallaunched_ondateis_activeboolean
| product_id | name | category | subcategory | unit_price | unit_cost | launched_on | is_active |
|---|---|---|---|---|---|---|---|
| 101 | Vale Velvet Loveseat | Furniture | Sofas | 1659.00 | NaN | 2023-09-11 | true |
| 102 | Alder Oak Coffee Table | Furniture | Tables | 919.00 | 503.50 | 2024-05-16 | true |
| 103 | Orchard Rattan Dining Chair | Furniture | Chairs | 789.00 | 429.87 | 2023-05-27 | true |
| 104 | Upland Oak Bookcase | Furniture | Storage | 429.00 | 214.70 | 2022-12-20 | true |
| 105 | Avery Leather Bed Frame | Furniture | Beds | 449.00 | 232.70 | 2021-08-31 | true |
returns1,673 filas · 5 columnas
return_idintegerorder_item_idintegerreturned_ondatereasonvarcharrefund_amountdecimal
| return_id | order_item_id | returned_on | reason | refund_amount |
|---|---|---|---|---|
| 1 | 14 | 2023-01-10 | damaged | 83.69 |
| 2 | 42 | 2023-01-10 | wrong_item | 19.99 |
| 3 | 105 | 2023-01-14 | wrong_item | 10.99 |
| 4 | 24 | 2023-01-16 | changed_mind | 26.99 |
| 5 | 126 | 2023-01-16 | late | 20.99 |
employees60 filas · 8 columnas
employee_idintegerfirst_namevarcharlast_namevarchardepartmentvarchartitlevarcharmanager_idintegerhire_datedatesalaryinteger
| employee_id | first_name | last_name | department | title | manager_id | hire_date | salary |
|---|---|---|---|---|---|---|---|
| 1 | Catherine | Hale | Executive | Chief Executive Officer | NaN | 2016-03-01 | 285000 |
| 2 | Robert | Kim | Executive | Chief Operating Officer | 1 | 2017-01-09 | 235000 |
| 3 | Megan | Collins | Sales | Head of Sales | 1 | 2018-04-16 | 172000 |
| 4 | Chloe | Gutierrez | Sales | Account Executive | 3 | 2020-01-21 | 72000 |
| 5 | Frank | Bell | Sales | Account Executive | 3 | 2023-05-21 | 73000 |
web_sessions40,000 filas · 7 columnas
session_idintegercustomer_idintegerstarted_attimestampdevicevarcharsourcevarcharpages_viewedintegerconvertedboolean
| session_id | customer_id | started_at | device | source | pages_viewed | converted |
|---|---|---|---|---|---|---|
| 1 | NaN | 2023-01-01 23:02:24 | mobile | paid | 1 | false |
| 2 | 18 | 2023-01-01 15:07:49 | desktop | paid | 1 | false |
| 3 | NaN | 2023-01-01 16:55:46 | desktop | direct | 7 | false |
| 4 | NaN | 2023-01-01 12:43:28 | mobile | organic | 3 | false |
| 5 | NaN | 2023-01-01 13:06:21 | mobile | social | 2 | false |
marketing_spend3,276 filas · 3 columnas
spend_datedatechannelvarcharamountdecimal
| spend_date | channel | amount |
|---|---|---|
| 2023-01-01 | paid | 492.99 |
| 2023-01-01 | 37.38 | |
| 2023-01-01 | social | 200.53 |
| 2023-01-02 | paid | 709.13 |
| 2023-01-02 | 64.13 |
La lección
Una tabla, cuatro vistas del tiempo
Cada paso parte de lines: una fila por línea de pedido de un pedido completado, con su
line_revenue y el order_date del pedido. A partir de ahí, el tiempo se puede cortar de dos
maneras. Resampling mete las filas en periodos consecutivos de una línea temporal (2 de
diciembre de 2025, la semana que termina en él, noviembre de 2025). Las partes de fecha extraen
una pieza de cada fecha (su día de la semana, su mes del año, su trimestre) para poder agrupar filas
de años distintos. El desafío necesita ambas.
Partes de fecha con .dt
El accesor .dt extrae partes de una columna datetime:
d = lines["order_date"]
d.dt.year # 2025
d.dt.quarter # 1 to 4
d.dt.month # 1 to 12
d.dt.month_name() # 'November'
d.dt.day_name() # 'Friday'
year, quarter y month son atributos (sin paréntesis) y devuelven números; month_name() y
day_name() son métodos y devuelven texto. Para cualquier otra etiqueta, strftime da formato a
una fecha con códigos: "%Y-%m" da '2025-11', "%b" da 'Nov', "%B" el nombre completo, "%a"
un día de la semana abreviado. En un DatetimeIndex los mismos métodos están disponibles
directamente, sin .dt: table.index.strftime("%b").
Meses en orden de calendario
Los nombres de mes son texto, y el texto se ordena alfabéticamente: April, August, December… Para mantener el orden de calendario, lleva el número del mes junto al nombre y ordena por el número:
parts = lines.assign(month_num=lines["order_date"].dt.month, month=lines["order_date"].dt.month_name())
parts.groupby(["month_num", "month"], as_index=False)["line_revenue"].sum().sort_values("month_num")
Agrupar por ambas claves no cuesta nada (cada número tiene un nombre) y te da una columna por la que
ordenar. Otra opción es una categórica ordenada, pd.Categorical(names, categories=[...], ordered=True), pero un número de mes es más simple y sobrevive a cualquier merge.
Promediar un mes a lo largo de tres años necesita dos pasos: primero sumar por año y mes, y luego promediar esos totales. Promediar las líneas directamente daría la línea de pedido media, no el mes medio.
Ventanas móviles y crecimiento, primero el historial
La mejor semana de 2025 es una suma móvil de 7 días sobre una serie diaria, construida sobre todo el historial y filtrada a 2025 después. Termina el jueves 4 de diciembre de 2025 con $104,267.39, cuando la ventana contiene todo el tramo del Black Friday al Cyber Monday. En 2024 la mejor ventana fue mayor, $117,208.44.
La misma regla se aplica al crecimiento interanual: pct_change(12) necesita los meses de 2024 en
la serie, así que selecciona el T4 de 2025 solo al final. La respuesta es incómoda: los ingresos de
noviembre de 2025 cayeron un 8,4 % respecto a noviembre de 2024 aunque el número de pedidos creció
un 13,7 %, el tipo de resultado que se informa con franqueza, con el recuento de pedidos al lado.
Cuotas de cada año
transform("sum") devuelve el total del grupo en cada fila del grupo, así que la cuota de un
trimestre en su año es una división. El T4 aportó 0.375 de los ingresos de 2023, 0.381 de los de 2024 y 0.328 de los de 2025.
Errores comunes
- Ordenar los nombres de los meses alfabéticamente en lugar de por número de mes.
- Escribir
dt.month_namesin paréntesis, lo que da un método, no nombres. - Filtrar a 2025 antes de
rollingopct_change(12), lo que convierte el inicio del periodo en NaN. - Dividir entre el total general de todos los años en lugar del total propio de cada año.
¡Linterna encendida!
Practicaste: rollingday namemonth namecalendar orderstrftimequarteryear over year
- Resuelto
- Sin pistas
- Al primer intento
