La solicitud

De Angela Rivera, Directora de Atención al Cliente
Tu objetivo
A partir de costed (construido en el starter: líneas válidas de pedidos confirmados, de 2023 a 2025, con costo unitario conocido, con net, cogs, refund (0 si no se devolvió) y returned (True/False)), asigna a result un DataFrame con una fila por categoría y las columnas category, net_sales, refunds, refund_rate_pct (refunds × 100 / net_sales), line_return_rate_pct (líneas devueltas × 100 / líneas) y margin_lost (la suma de net − cogs en las líneas devueltas), todas redondeadas a 2, ordenado por refund_rate_pct de mayor a menor.
- Usa el DataFrame
productspendiente - Usa el DataFrame
orderspendiente - Muestra exactamente
categorynet_salesrefundsrefund_rate_pctline_return_rate_pctmargin_lostpendiente
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 Angela, 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 |
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 |
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 |
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
Dos tasas de devolución
“Tasa de devolución” esconde una elección de unidad:
- Tasa en dólares = reembolsos ÷ ventas netas. Qué parte del dinero volvió.
- Tasa por líneas = líneas devueltas ÷ todas las líneas. Qué parte de lo vendido volvió.
Cuando los artículos de una categoría tienen precios parecidos, las dos coinciden. Cuando una categoría mezcla lámparas de $40 con lámparas de pie de $400, pueden diferir, y una diapositiva que dice “tasa de devolución 6,7 %” sin la unidad puede leerse de las dos maneras.
Un left join conserva todas las líneas
Las devoluciones viven en su propia tabla, una fila por línea devuelta. Un merge a la izquierda desde
las líneas conserva cada venta y agrega refund_amount donde hubo devolución:
lines.merge(returns[["order_item_id", "refund_amount"]], on="order_item_id", how="left")
refund_amount es NaN en las líneas que no se devolvieron. notna() lo convierte en un indicador
True/False returned, y fillna(0) lo convierte en un reembolso de cero, así que las dos tasas son
simples sumas y medias sobre las mismas filas.
Margen perdido
Un reembolso devuelve los ingresos, pero el costo de la mercancía ya se pagó. Si el artículo vuelve dañado, la tienda pierde también su costo; si se puede revender, se recupera buena parte. Este nivel usa un indicador aproximado, simple y honesto: el margen bruto de las líneas devueltas, la ganancia que la tienda registró en esas ventas y luego devolvió. Di en la diapositiva que es una aproximación, y que la mercancía dañada cuesta más.
Tasa frente a dólares
La categoría con la tasa más alta no siempre es la que más pierde. La tasa de Lighting está en el medio, pero vende tanto que sus devoluciones cuestan más margen que las de cualquier otra categoría. Muestra la tasa al equipo que puede bajarla, y los dólares al equipo que fija las prioridades.
Errores comunes
- Una tasa sobre el denominador equivocado. Reembolsos sobre todos los pedidos, incluidos los cancelados, o sobre ventas brutas antes de descuentos, subestiman la tasa.
- Un join interno con returns. Solo quedan las líneas devueltas, así que cada tasa se vuelve 100 %.
- Confundir reembolsos con ventas netas de las líneas devueltas. Las tarifas de reposición hacen que los reembolsos sean un poco menores que el valor neto de las líneas.
¡Linterna encendida!
Practicaste: return raterefundsdenominatorsmargin lostmerge
- Resuelto
- Sin pistas
- Al primer intento
