La solicitud

De Laura Bennett, Directora de Finanzas
Tu objetivo
El código del starter se ejecuta pero cuenta los pedidos equivocados. Corrígelo para que result sea el número de pedidos (un int) cuyo canal es 'web' o 'app' Y cuyo shipping_fee es mayor que 0.
- Usa el DataFrame
orderspendiente - Guarda un número en
resultpendiente
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.
Lo que recibe Laura, 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 |
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 |
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 |
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
Por qué el número es imposible
La comprobación de Laura es el mejor tipo de depuración: un límite. 3,977 pedidos pagaron algún envío, así que «pedidos de web y app que pagaron envío» debe ser un número menor. 6,867 es mayor, así que el filtro está dejando entrar filas que no debería. Antes de tocar el código, pregúntate qué filas podrían estar colándose.
La respuesta está en cómo agrupa Python & y |. Igual que * se evalúa antes que + en aritmética,
& se evalúa antes que |. La condición del starter
(orders["channel"] == "web") | (orders["channel"] == "app") & (orders["shipping_fee"] > 0)
la lee Python como
(orders["channel"] == "web") | ((orders["channel"] == "app") & (orders["shipping_fee"] > 0))
Eso es «todos los pedidos web, más los pedidos de app que pagaron envío». Hay 5,913 pedidos web y 954 pedidos de app con envío pagado: 5,913 + 954 = 6,867, exactamente el número erróneo del borrador.
La corrección: agrupa tú el «o»
Pon la parte «web o app» entre sus propios paréntesis para que se decida primero:
web_or_app = (orders["channel"] == "web") | (orders["channel"] == "app")
paid = orders["shipping_fee"] > 0
orders[web_or_app & paid]
Ponerle nombre a las máscaras, como arriba, hace que la lógica sea fácil de leer e imposible de agrupar
mal. Una opción más corta evita | por completo:
orders[orders["channel"].isin(["web", "app"]) & (orders["shipping_fee"] > 0)]
Ambas dan 2,210 pedidos: 1,256 de web y 954 de la app. Los pedidos del marketplace quedan excluidos aunque 1,767 de ellos pagaron envío, que es una proporción grande: las comisiones del marketplace siguen otras reglas.
Comprobar una corrección
Después de una corrección, prueba las piezas por separado: cuenta los pedidos de web o app (10,233), cuenta
los que pagaron (3,977) y confirma que el filtro combinado no es mayor que ninguno de los dos. Dos números
rápidos como estos detectan la mayoría de los errores de filtro. Puedes contar una máscara directamente con
.sum(), porque True cuenta como 1, así que ni siquiera necesitas filtrar la tabla para comprobar cada
pieza. Luego suma de nuevo los conteos por canal y asegúrate de que coinciden con el número combinado.
Errores comunes
- Fiarte de la lectura de izquierda a derecha.
a | b & csignificaa | (b & c). - Omitir los paréntesis alrededor de cada comparación:
orders["channel"] == "web" | ...falla con un TypeError, porque|se evalúa antes que==. - Usar
and/orcon Series, lo que lanzaValueError: The truth value of a Series is ambiguous. - Devolver el DataFrame filtrado en lugar de su número de filas. El ticket pide un número.
¡Linterna encendida!
Practicaste: boolean maskand or notparenthesesoperator precedencedebugging
- Resuelto
- Sin pistas
- Al primer intento
