La solicitud

De Catherine Hale, CEO
Tu objetivo
Paso 1 de 3. Mide el desorden en customers. Asigna a result un DataFrame de una fila con las columnas customer_rows (todas las filas), people (correos distintos tras .str.strip().str.lower()), raw_states y clean_states (state distintos antes y después de .str.strip().str.upper()), raw_cities y clean_cities (lo mismo para city) y missing_city (filas con ciudad ausente).
- Usa el DataFrame
customerspendiente - Muestra exactamente
customer_rowspeopleraw_statesclean_statesraw_citiesclean_citiesmissing_citypendiente - 1 fila, ordenadas como se pidependiente
Paso 2 de 3. Clasifica los estados limpios. Asigna a result un DataFrame con las columnas state (limpio), customers (personas distintas en ese estado, de customers, hayan pedido o no), buyers_2025 (customer_id distintos con una línea contada en 2025), revenue_2024 y revenue_2025 (ingresos netos, redondeados a 2), growth_pct ((2025 - 2024) * 100 / 2024 a partir de sumas sin redondear, redondeado a 1) y revenue_per_buyer (ingresos 2025 / buyers_2025, redondeado a 2). Conserva los 10 mejores estados por revenue_2025, de mayor a menor, con índice por defecto.
- Usa el DataFrame
customerspendiente - Usa el DataFrame
orderspendiente - Muestra exactamente
statecustomersbuyers_2025revenue_2024revenue_2025growth_pctrevenue_per_buyerpendiente
Paso 3 de 3. Clasifica las áreas metropolitanas para una sala de exposición. Usa solo clientes consumidores (segment == 'consumer') con ciudad conocida. Asigna a result un DataFrame con las columnas city (limpia), state (limpio), buyers_2025, revenue_2024, revenue_2025 (redondeados a 2) y growth_pct (redondeado a 1), calculados como en el paso 2. Conserva las 8 mejores áreas por revenue_2025, de mayor a menor, con índice por defecto.
- Usa el DataFrame
customerspendiente - Usa el DataFrame
orderspendiente - Muestra exactamente
citystatebuyers_2025revenue_2024revenue_2025growth_pctpendiente
Este caso se desbloquea cuando terminas cualquiera de estos:
La solicitud y la lección ya se pueden leer. Resuelve todos los niveles de uno de esos capítulos, en la ruta que prefieras, y este caso se abre.
Paso 1 · tu código
Cargando el editor…
Solución de referencia
| customer_id | first_name | last_name | city | |
|---|---|---|---|---|
| 1 | Owen | Hudson | owen.hudson@icloud.com | San Francisco |
| 2 | Douglas | Mendoza | dmendoza69@gmail.com | Atlanta |
| 3 | Henry | Brooks | hbrooks@lakesidecafe.com | Los Angeles |
| 4 | Brian | Graham | bgraham@bluecedarhomes.com | Seattle |
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
| customer_id | first_name | last_name | city | |
|---|---|---|---|---|
| 1 | Owen | Hudson | owen.hudson@icloud.com | San Francisco |
| 2 | Douglas | Mendoza | dmendoza69@gmail.com | Atlanta |
| 3 | Henry | Brooks | hbrooks@lakesidecafe.com | Los Angeles |
| 4 | Brian | Graham | bgraham@bluecedarhomes.com | Seattle |
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
| customer_id | first_name | last_name | city | |
|---|---|---|---|---|
| 1 | Owen | Hudson | owen.hudson@icloud.com | San Francisco |
| 2 | Douglas | Mendoza | dmendoza69@gmail.com | Atlanta |
| 3 | Henry | Brooks | hbrooks@lakesidecafe.com | Los Angeles |
| 4 | Brian | Graham | bgraham@bluecedarhomes.com | Seattle |
Mote revisa tu resultado
Presiona Ejecutar. Cada fila que cumple el objetivo se vuelve una luciérnaga en tu linterna.
Lo que recibe Catherine, y por qué
DataFrames
Cargados como DataFrames de pandas, junto con pd y np.
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 |
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 |
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 |
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
Qué estás verificando y por qué
Las direcciones de los clientes las escriben los clientes, así que el mismo lugar llega con varias grafías. Antes de
agrupar por nada, mide cuán grave es. nunique() sobre la columna sin procesar frente al mismo conteo
sobre los valores limpios te lo dice en dos líneas:
customers["state"].nunique() # 69 labels
customers["state"].str.strip().str.upper().nunique() # 39 states
.str.strip() quita los espacios sueltos y .str.upper() pone todas las etiquetas en una misma capitalización. A las personas se las
empareja igual, por el correo limpio, porque un correo es lo más parecido que tiene la tabla a la identidad de una
persona: el customer_id cambia cuando alguien se registra de nuevo.
Los métodos .str dejan NaN como NaN y nunique() lo omite, así que las 14 ciudades en blanco quedan fuera del
conteo en lugar de convertirse en una ciudad llamada “NAN”. isna().sum() las cuenta; no se pueden ubicar en un
área metropolitana y salen del paso 3.
Primero estados, luego áreas metropolitanas
El paso 2 le da a la junta la vista por estado, que ya conoce. Mezcla dos fuentes: customers para saber cuántas
personas viven en cada estado, y las líneas de pedido para saber quién compró y cuánto. Cada lado se agrega
por separado, como una Series indexada por estado, y pd.DataFrame({...}) las alinea por ese índice.
El paso 3 es la respuesta a la pregunta de la sala de exposición. Conserva solo consumidores, porque las cuentas de empresa piden en línea y no visitarían, y clasifica áreas metropolitanas, porque una sala de exposición sirve a una ciudad:
c = customers[(customers["segment"] == "consumer") & customers["city"].notna()]
r = lines.pivot_table(index=["city", "state"], columns="yr", values="revenue", aggfunc="sum")
Las columnas del pivote son los años como enteros, así que r[2025] - r[2024] resta fila por fila. Calcula
el crecimiento sobre estos totales sin redondear y redondea al final.
Cómo leer el resultado
| city | buyers_2025 | revenue_2025 | growth_pct |
|---|---|---|---|
| NEW YORK | 104 | 96,984.37 | −5.9 |
| LOS ANGELES | 78 | 71,631.90 | 30.7 |
| DALLAS | 58 | 66,362.59 | 17.2 |
New York es la mayor y Los Angeles la de más rápido crecimiento entre las líderes. La tabla por estado habría señalado a California en su conjunto, y su crecimiento global de 0.3% habría ocultado que Los Angeles crece rápido.
Trampas
- Limpiar una copia y luego hacer merge con la tabla sin procesar vuelve a dividir los grupos. Limpia una vez, en
customers, y haz merge de las columnas limpias. customers["city"] != customers["city"].str.strip()esTruepara todo NaN, porque NaN nunca es igual a nada. Cuenta los valores desordenados con.notna()en la máscara.head(10)sinsort_valuesdevuelve los diez primeros estados en orden alfabético.
¡Linterna encendida!
Practicaste: data cleaningstring methodsnuniquededuplicationmergepivot tableyoy
- Resuelto
- Sin pistas
- Al primer intento
