La solicitud

De Angela Rivera, Directora de Atención al Cliente
Tu objetivo
Une cada devolución con su línea de pedido y su producto. Asigna a result un DataFrame con las columnas category, changed_mind, damaged, late, wrong_item: para cada categoría, la proporción de las devoluciones de esa categoría con cada motivo (cada fila suma 1), redondeada a 3. Una fila por categoría, ordenada de la A a la Z.
- Usa el DataFrame
productspendiente - Usa el DataFrame
order_itemspendiente - Muestra exactamente
categorychanged_minddamagedlatewrong_itempendiente
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 |
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 |
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 |
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
crosstab: una cuadrícula de recuentos a partir de dos columnas
pd.crosstab es un atajo para el pivot más común: contar con qué frecuencia ocurre cada par de
valores. Le pasas las dos columnas directamente:
pd.crosstab(web_sessions["device"], web_sessions["converted"])
# converted False True
# device
# desktop 13978 563
# mobile 21029 520
# tablet 3800 110
El primer argumento pasa a ser las filas, el segundo las columnas. Los pares vacíos son 0, no NaN,
porque un recuento de nada es cero. Es una función del módulo pandas (pd.crosstab), no un método
de DataFrame, así que las columnas pueden incluso venir de tablas distintas siempre que sus filas se alineen.
normalize: cuotas en lugar de recuentos
Los recuentos brutos engañan cuando los grupos difieren en tamaño. Mobile tuvo 520 conversiones,
cerca de las 563 de desktop, pero a partir de muchas más sesiones. El argumento normalize divide por un total:
normalize="index": cada celda ÷ el total de su fila. Cada fila suma 1. “De las sesiones en mobile, ¿qué proporción convirtió?”normalize="columns": cada celda ÷ el total de su columna. Cada columna suma 1. “De las sesiones que convirtieron, ¿qué proporción fueron en mobile?”normalize=True(o"all"): cada celda ÷ el total general.
pd.crosstab(web_sessions["device"], web_sessions["converted"], normalize="index").round(3)
# converted False True
# desktop 0.961 0.039
# mobile 0.976 0.024
# tablet 0.972 0.028
Desktop convierte al 3,9 % frente al 2,4 % de mobile: la cuota cuenta la historia que los recuentos ocultaban.
Elegir la dirección
Di la pregunta en voz alta y escucha el “de”. “De las devoluciones de cada categoría, ¿qué proporción es damaged?” divide por el total de la categoría (fila). “De todas las devoluciones damaged, ¿qué proporción es Furniture?” divide por el total del motivo (columna). Las dos dan números distintos a partir de los mismos recuentos, y ambas son respuestas correctas a preguntas distintas.
margins=True añade una fila y una columna All con los totales, que es una forma rápida de
comprobar los recuentos antes de normalizar: en los datos de devoluciones el total general es 1.673,
todas las devoluciones de la tabla.
Obtener la categoría
Las devoluciones no llevan una categoría. Cada devolución apunta a una línea de pedido
(order_item_id), la línea apunta a un producto, y el producto tiene la categoría. Dos merges la
traen, y como cada devolución coincide con exactamente una línea y cada línea con un producto, el
número de filas se mantiene en 1.673.
Errores comunes
- Normalizar en la dirección equivocada. Las filas suman 1 con
"index", las columnas con"columns". - Comparar recuentos brutos entre grupos de tamaños muy distintos.
- Pasar nombres de columna como cadenas,
pd.crosstab("category", "reason"). crosstab recibe las columnas mismas, no sus nombres. - Informar cuotas sin los recuentos en que se apoyan. El 45,6 % de damaged de Furniture se apoya en solo 103 devoluciones; dilo.
¡Linterna encendida!
Practicaste: crosstabnormalizesharesmerge
- Resuelto
- Sin pistas
- Al primer intento
