La solicitud

De Angela Rivera, Directora de Atención al Cliente
Tu objetivo
Paso 1 de 3. Revisa dónde están las devoluciones. Para cada línea de pedido, sea cual sea su cantidad, asigna a result un DataFrame con las columnas status, lines (el número de líneas de pedido), returned_lines (líneas cuyo order_item_id aparece en returns) y return_rate_pct (returned_lines * 100 / lines, redondeado a 1), ordenado por status y con índice por defecto.
- Usa el DataFrame
orderspendiente - Usa el DataFrame
order_itemspendiente - Muestra exactamente
statuslinesreturned_linesreturn_rate_pctpendiente
Paso 2 de 3. Mide la tasa por categoría. Usa pedidos completados y líneas con quantity > 0. Asigna a result un DataFrame con las columnas category, sold_lines, returned_lines, return_rate_pct (returned_lines * 100 / sold_lines), net_sales (ingreso neto por línea, redondeado a 2), refunds (suma de refund_amount, redondeada a 2) y refund_share_pct (refunds * 100 / net_sales). Ambos porcentajes salen de valores sin redondear y se redondean a 1. Ordena por return_rate_pct de forma descendente, con índice por defecto.
- Usa el DataFrame
productspendiente - Usa el DataFrame
orderspendiente - Muestra exactamente
categorysold_linesreturned_linesreturn_rate_pctnet_salesrefundsrefund_share_pctpendiente
Paso 3 de 3. Explica la tasa con los motivos. Usa las devoluciones de pedidos completados. Asigna a result un DataFrame con las columnas category, returns (el número de devoluciones) y damaged_pct, changed_mind_pct, wrong_item_pct y late_pct: la proporción de cada motivo sobre las devoluciones de esa categoría, * 100, redondeada a 1. Ordena por category, con índice por defecto.
- Usa el DataFrame
productspendiente - Usa el DataFrame
orderspendiente - Muestra exactamente
categoryreturnsdamaged_pctchanged_mind_pctwrong_item_pctlate_pctpendiente
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
| 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.
Paso 3 · 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.
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 |
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 |
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
Qué estás revisando, y por qué
Antes de calcular una tasa, mira a qué pertenecen las devoluciones. Cada fila de devolución apunta a una línea de pedido, y cada línea pertenece a un pedido con un estado. Si las devoluciones se comportan de forma muy distinta según el estado, una sola tasa para todo lo ocultaría.
La forma más rápida de marcar las líneas devueltas es isin, que da un True o False por línea:
lines["returned"] = lines["order_item_id"].isin(returns["order_item_id"])
Sumar una columna booleana cuenta los valores True, así que ("returned", "sum") en una agregación
con nombre es el número de líneas devueltas. El resultado del paso 1 muestra los pedidos reembolsados
en 96.6% y los completados en 3.3%: dos procesos distintos, y por eso el resto del caso usa solo
pedidos completados.
La tasa y el dinero
El paso 2 también necesita el importe del reembolso, así que une returns con how="left". Cada
línea vendida se conserva; las líneas devueltas reciben su refund_amount, las demás reciben NaN.
Dos agregaciones hacen entonces el conteo por ti:
("order_item_id", "size")cuenta todas las líneas, el denominador;("refund_amount", "count")cuenta los valores no faltantes, las líneas devueltas.
De la misma tabla salen la tasa de devolución, que le dice a Atención al Cliente dónde está el trabajo, y la proporción de reembolso, los reembolsos divididos entre las ventas netas, que le dice a Finanzas adónde va el dinero. Calcula ambos porcentajes con las sumas sin redondear y redondea al final.
Motivos como columnas
El paso 3 parte de returns, ya que solo las líneas devueltas tienen un motivo. pd.crosstab cuenta
cada par de categoría y motivo, y normalize="index" convierte cada fila en proporciones de esa
fila:
shares = pd.crosstab(r["category"], r["reason"], normalize="index") * 100
Cada fila suma entonces 100%, la versión en pandas de dividir entre el COUNT(*) de la propia
categoría.
Cómo leer el resultado
| category | return_rate_pct | refund_share_pct | motivo principal |
|---|---|---|---|
| Textiles | 4.7 | 5.1 | changed_mind 57.9% |
| Furniture | 4.4 | 4.7 | damaged 46.0% |
| Lighting | 3.8 | 4.3 | damaged 38.3% |
| Kitchen | 2.0 | 2.5 | changed_mind 40.6% |
Aparecen dos problemas distintos. Textiles regresa porque los clientes cambian de opinión: el color, el tacto o la talla no son los esperados. Furniture y Lighting regresan rotos. Esos casos necesitan soluciones diferentes.
Errores comunes
mergees un JOIN interno a menos que digashow="left"; con returns eso descarta sin avisar toda línea que no se devolvió."count"omite los NaN y"size"no; confundirlos da una tasa de 100% o de 0%.- Algunos reembolsos por cambio de opinión en Furniture y Outdoor son 15% menores que el valor de la línea: un cargo por reposición. Compara los reembolsos con las ventas, no con los valores de las líneas devueltas, cuando hables del dinero perdido.
¡Linterna encendida!
Practicaste: data validationisinleft mergenamed aggregationcrosstabreturn rate
- Resuelto
- Sin pistas
- Al primer intento
