La solicitud

De Jordan Reyes, Director de Marketing
Tu objetivo
marketing_spend debería tener una fila por día y canal de 2023-01-01 a 2025-12-31. Asigna a result un DataFrame con las columnas channel, missing_days (días de ese rango sin fila para el canal), recorded_total (suma de amount tal como se registró, redondeada a 2) y filled_total (suma tras rellenar cada día ausente con el amount del día anterior de ese canal, redondeada a 2), una fila por canal, ordenado por channel de la A a la Z, con el índice reiniciado.
- Usa el DataFrame
marketing_spendpendiente - Muestra exactamente
channelmissing_daysrecorded_totalfilled_totalpendiente - 3 filas, ordenadas como se pidependiente
Tu código
Cargando el editor…
Solución de referencia
| 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 |
Mote revisa tu resultado
Presiona Ejecutar. Cada fila que cumple el objetivo se vuelve una luciérnaga en tu linterna.
Lo que recibe Jordan, y por qué
DataFrames
Cargados como DataFrames de pandas, junto con pd y np.
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 |
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 |
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 |
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 |
La lección
Las filas ausentes son invisibles
Un valor ausente que puedes ver es fácil: es NaN, y isna() lo encuentra. Una fila ausente es
más difícil. Si el registro tuvo una caída el 28 de enero de 2023, simplemente no hay fila de paid
para ese día, y nada en la tabla te lo dice. resample y rolling pasan alegremente sobre el
agujero, y una ventana rolling(7) cubre en silencio 8 días del calendario.
La solución es colocar los datos en un calendario completo, de modo que cada día que debería existir tenga una fila, y los ausentes aparezcan como NaN.
asfreq para una serie
Para una sola serie con un DatetimeIndex, asfreq("D") lo hace en una llamada:
paid = marketing_spend[marketing_spend["channel"] == "paid"].set_index("spend_date")["amount"]
len(paid) # 1091
filled = paid.asfreq("D")
len(filled) # 1096
filled.isna().sum() # 5
asfreq construye un índice diario regular desde la primera hasta la última fecha e inserta NaN
donde no había fila. Tres años son 1.096 días (2024 es bisiesto), así que al canal paid le faltan 5 días.
reindex con date_range para muchas columnas
asfreq solo rellena entre la primera y la última fecha presentes. Si faltara toda la primera
semana, no podría saberlo. pd.date_range te permite indicar explícitamente el calendario esperado,
y reindex coloca la tabla en él:
days = pd.date_range("2023-01-01", "2025-12-31", freq="D")
wide = marketing_spend.pivot(index="spend_date", columns="channel", values="amount").reindex(days)
wide.isna().sum()
# email 4, paid 5, social 3
pivot convierte la tabla larga en una columna por canal (el capítulo 9 lo cubre en profundidad),
así que los tres canales se comprueban a la vez contra el mismo calendario.
Elegir un relleno
Cuando los huecos son visibles, tú decides qué significan. Para el gasto de paid, la media diaria sale distinta según esa elección:
- Omitirlos (el valor por defecto de
mean()ysum()): media de $814.64 sobre los 1.091 días registrados. fillna(0): “no se gastó nada”. Media de $810.93 sobre 1.096 días. Incorrecto aquí: el dinero se gastó, solo falló el registro.ffill(): traslada el último valor conocido hacia delante. El total sube de $888,774.13 a $892,327.94.interpolate(): una línea recta entre los vecinos, total $892,420.97.
Cero es correcto cuando un día ausente significa realmente cero (sin pedidos en un día de cierre). El relleno hacia delante o la interpolación es correcto cuando el valor existió pero no se registró. Di cuál usaste.
Errores comunes
- Ejecutar
rolling(7)en una serie con días ausentes, de modo que la ventana es más larga que una semana. - Usar
fillna(0)para una caída, lo que subestima el gasto y sobrestima el retorno de la inversión publicitaria. - Usar
asfreqcuando los huecos pueden estar justo al principio o al final del rango;reindexcon undate_rangeexplícito los detecta. - Olvidar que
sum()ymean()omiten los NaN, así que una tabla con huecos igualmente “suma”, pero a una cifra equivocada.
¡Linterna encendida!
Practicaste: asfreqdate rangereindexffillfillnamissing dates
- Resuelto
- Sin pistas
- Al primer intento
