La solicitud

De Jordan Reyes, Director de Marketing
Tu objetivo
Paso 1 de 3. Asigna a result el número de sesiones (un int) donde device es 'mobile', source es 'paid' y converted es True.
- Usa el DataFrame
web_sessionspendiente - Guarda un número en
resultpendiente
Paso 2 de 3. Entre las sesiones con pages_viewed de 10 o más, asigna a result la proporción que convirtió (un float entre 0 y 1), redondeada a 3 decimales.
- Usa el DataFrame
web_sessionspendiente - Guarda un número en
resultpendiente
Paso 3 de 3. Asigna a result un DataFrame de las 15 sesiones con source 'email' que vieron más páginas: columnas session_id, device, pages_viewed, converted, ordenadas por pages_viewed descendente y luego session_id ascendente, índice reiniciado.
- Usa el DataFrame
web_sessionspendiente - Muestra exactamente
session_iddevicepages_viewedconvertedpendiente - 15 filas, ordenadas como se pidependiente
Paso 1 · tu código
Cargando el editor…
Solución de referencia
| session_id | customer_id | started_at | device | source |
|---|---|---|---|---|
| 1 | NaN | 2023-01-01 23:02:24 | mobile | paid |
| 2 | 18 | 2023-01-01 15:07:49 | desktop | paid |
| 3 | NaN | 2023-01-01 16:55:46 | desktop | direct |
| 4 | NaN | 2023-01-01 12:43:28 | mobile | organic |
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
| session_id | customer_id | started_at | device | source |
|---|---|---|---|---|
| 1 | NaN | 2023-01-01 23:02:24 | mobile | paid |
| 2 | 18 | 2023-01-01 15:07:49 | desktop | paid |
| 3 | NaN | 2023-01-01 16:55:46 | desktop | direct |
| 4 | NaN | 2023-01-01 12:43:28 | mobile | organic |
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
| session_id | customer_id | started_at | device | source |
|---|---|---|---|---|
| 1 | NaN | 2023-01-01 23:02:24 | mobile | paid |
| 2 | 18 | 2023-01-01 15:07:49 | desktop | paid |
| 3 | NaN | 2023-01-01 16:55:46 | desktop | direct |
| 4 | NaN | 2023-01-01 12:43:28 | mobile | organic |
Mote revisa tu resultado
Presiona Ejecutar. Cada fila que cumple el objetivo se vuelve una luciérnaga en tu linterna.
Lo que recibe Jordan, y por qué
DataFrames
Cargados como DataFrames de pandas, junto con pd y np.
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 |
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 |
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 |
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 |
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
Un conjunto de datos de embudo
web_sessions tiene una fila por visita al sitio web: cuándo empezó, el dispositivo, la fuente de
tráfico, cuántas páginas vio el visitante y si la visita terminó en una compra. Son 40,000 filas, y cada
pregunta de este nivel es un filtro seguido de un conteo, una proporción o una ordenación.
Paso 1: contar con una máscara
No necesitas filtrar filas para contarlas. Una máscara es una columna de True y False, y True cuenta
como 1:
mask = (
(web_sessions["device"] == "mobile")
& (web_sessions["source"] == "paid")
& web_sessions["converted"]
)
mask.sum()
Fíjate en que la última condición no lleva == True. converted ya es booleana, así que es una máscara
por sí sola. Escribir web_sessions["converted"] == True también funciona, pero es redundante. .sum()
sobre una máscara devuelve un entero de NumPy; envolverlo en int() da un número normal de Python.
Paso 2: una tasa es una media
La proporción de sesiones que convirtieron es el número de valores True dividido entre el número de filas, que es exactamente la media de una columna booleana:
engaged = web_sessions[web_sessions["pages_viewed"] >= 10]
engaged["converted"].mean()
Este es uno de los trucos más útiles de pandas. La tasa de conversión, la tasa de devoluciones, la
proporción de pedidos con cupón: cada una es la .mean() de la máscara correcta, sobre el conjunto de
filas correcto. El «conjunto de filas correcto» es la parte importante. La conversión «entre las sesiones
comprometidas» tiene un denominador distinto al de la conversión sobre todas las sesiones, y confundirlos
es uno de los errores más comunes en los informes de embudo.
Compárala con la tasa general, web_sessions["converted"].mean(). La tasa de las comprometidas es mucho
más alta, lo cual es esperable: alguien que navega diez páginas tiene muchas más probabilidades de
comprar. Eso no significa que hacer que la gente vea más páginas haría que comprara; la interacción y la
intención de compra se mueven juntas. Mantén separadas la correlación y la causa cuando presentes esto.
Paso 3: una lista ordenada
email = web_sessions[web_sessions["source"] == "email"]
(
email.sort_values(["pages_viewed", "session_id"], ascending=[False, True])
.head(15)[["session_id", "device", "pages_viewed", "converted"]]
.reset_index(drop=True)
)
Muchas sesiones comparten el mismo número de páginas, así que session_id como desempate hace la lista
reproducible. Filtra primero, ordena después: ordenar 40,000 filas y filtrar más tarde da la misma
respuesta pero hace más trabajo, y es más fácil equivocarse en el orden de los pasos.
Leer los resultados como un profesional de marketing
- Un conteo de conversiones sin denominador es difícil de juzgar. «51 conversiones móviles de pago» significa poco hasta que sabes cuántas sesiones móviles de pago hubo.
- Las sesiones sin
customer_idson visitantes anónimos. En este conjunto de datos, solo convierten los clientes conocidos, lo que refleja cómo muchas tiendas registran las compras.
Errores comunes
- Usar
andentre máscaras en lugar de&. - Calcular la proporción del paso 2 sobre todas las sesiones en lugar de sobre las comprometidas.
- Ordenar solo por pages_viewed, de modo que la fila 15 cambia entre ejecuciones.
¡Linterna encendida!
Practicaste: boolean maskmean of booleansort valuesloc
- Resuelto
- Sin pistas
- Al primer intento
