La solicitud

De Daniel Brooks, Director de Operaciones
Tu objetivo
Asigna a result el total de shipping_fee (un float redondeado a 2) de los pedidos completados que contienen al menos una línea de pedido cuya categoría de producto es 'Lighting'. El gasto de cada pedido cuenta una sola vez, tenga las líneas que tenga.
- Usa el DataFrame
productspendiente - Usa el DataFrame
orderspendiente - Guarda un número en
resultpendiente
Tu código
Cargando el editor…
Solución de referencia
| product_id | name | category | subcategory | unit_price |
|---|---|---|---|---|
| 101 | Vale Velvet Loveseat | Furniture | Sofas | 1659.00 |
| 102 | Alder Oak Coffee Table | Furniture | Tables | 919.00 |
| 103 | Orchard Rattan Dining Chair | Furniture | Chairs | 789.00 |
| 104 | Upland Oak Bookcase | Furniture | Storage | 429.00 |
Mote revisa tu resultado
Presiona Ejecutar. Cada fila que cumple el objetivo se vuelve una luciérnaga en tu linterna.
Lo que recibe Daniel, y por qué
DataFrames
Cargados como DataFrames de pandas, junto con pd y np.
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 |
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 |
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
La pregunta cruza granos
La condición (“contiene un producto de Iluminación”) vive en el nivel de línea: necesitas
order_items y products para saberla. La medida (gasto de envío) vive en el nivel de pedido.
Mezclar las dos en una sola tabla unida es como ocurre el fan-out del nivel anterior.
La receta segura es:
- Usa las tablas de nivel línea para encontrar qué pedidos cumplen.
- Suma la medida de nivel pedido en la tabla orders, solo para esos pedidos.
Paso 1: IDs de pedido que cumplen
lines = order_items.merge(products[["product_id", "category"]], on="product_id")
lighting_ids = lines.loc[lines["category"] == "Lighting", "order_id"].unique()
.unique() convierte “el ID de pedido de cada línea de Iluminación” en una lista de pedidos
distintos. Un pedido con dos lámparas aparecería dos veces si no. Para isin no importa
estrictamente, ya que isin solo pregunta si un valor está presente, pero quitar duplicados deja
clara la intención y te permite comprobar len(lighting_ids) como número de pedidos.
Paso 2: suma en la tabla correcta
mask = (orders["status"] == "completed") & orders["order_id"].isin(lighting_ids)
orders.loc[mask, "shipping_fee"].sum()
Cada pedido aparece una vez en orders, así que cada gasto cuenta una vez. Ese es todo el truco.
La respuesta incorrecta, para comparar
wrong = (
orders.merge(lines, on="order_id")
.loc[lambda d: (d["status"] == "completed") & (d["category"] == "Lighting"), "shipping_fee"]
.sum()
)
Esto cuenta el gasto de un pedido una vez por cada línea de Iluminación que tenga. Un pedido con una lámpara colgante y dos lámparas en líneas separadas se cuenta tres veces. Es una forma muy natural de escribir el código, y por eso es un error tan común. Ejecuta ambas y compara; la diferencia es el tamaño del error.
Otra solución tentadora es drop_duplicates() sobre la tabla unida. Puede funcionar, pero solo si
quitas duplicados únicamente por order_id después de seleccionar columnas de nivel pedido. Llamarlo
sobre toda la tabla unida no hace nada, porque las columnas de línea hacen distinta cada fila.
Alternativa: agrega primero
También puedes subir la información de línea al grano de pedido y luego unir one-to-one:
has_lighting = (
lines.assign(is_lighting=lines["category"] == "Lighting")
.groupby("order_id", as_index=False)
.agg(has_lighting=("is_lighting", "any"))
)
orders.merge(has_lighting, on="order_id", validate="one_to_one")
Ahora cada pedido tiene una única marca True/False y puede sumarse, filtrarse o agruparse sin riesgo. Es el mejor enfoque cuando quieres varias marcas de nivel pedido a la vez (“tiene iluminación”, “tiene muebles”, “número de líneas”).
Interpretar el resultado
Para responder la pregunta real de Daniel, compara el gasto de envío medio de los pedidos con Iluminación con el medio de los demás pedidos completados. El total por sí solo no puede mostrar si Iluminación empuja los gastos hacia arriba; refleja sobre todo cuántos pedidos de Iluminación hay.
Errores comunes
- Sumar shipping_fee en la tabla unida de nivel línea.
- Olvidar el filtro de estado.
- Quitar duplicados en la tabla equivocada, o por las columnas equivocadas.
¡Linterna encendida!
Practicaste: fan outgrainisinuniquemerge
- Resuelto
- Sin pistas
- Al primer intento
