1. Faro

Nivel 2 · Limpia y clasifica las ubicaciones en pandas

La solicitud

De Catherine Hale, CEO

“Acordamos la pregunta: ingresos de consumidores por área metropolitana en 2025 y su crecimiento respecto a 2024, con los totales por estado al lado. Ryan me advirtió que las direcciones son un desastre, así que primero muéstrame cuánta limpieza necesitan.”

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_rows people raw_states clean_states raw_cities clean_cities missing_citypendiente
  • 1 fila, ordenadas como se pidependiente

Paso 1 · tu código

Python

Cargando el editor…

    ResultadoVista previa de customers · presiona Ejecutar para ver el tuyo
    Vista previa de customers
    customer_idfirst_namelast_nameemailcity
    1OwenHudsonowen.hudson@icloud.comSan Francisco
    2DouglasMendozadmendoza69@gmail.comAtlanta
    3HenryBrookshbrooks@lakesidecafe.comLos Angeles
    4BrianGrahambgraham@bluecedarhomes.comSeattle

    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

    Python

    Cargando el editor…

      ResultadoVista previa de customers · presiona Ejecutar para ver el tuyo
      Vista previa de customers
      customer_idfirst_namelast_nameemailcity
      1OwenHudsonowen.hudson@icloud.comSan Francisco
      2DouglasMendozadmendoza69@gmail.comAtlanta
      3HenryBrookshbrooks@lakesidecafe.comLos Angeles
      4BrianGrahambgraham@bluecedarhomes.comSeattle

      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

      Python

      Cargando el editor…

        ResultadoVista previa de customers · presiona Ejecutar para ver el tuyo
        Vista previa de customers
        customer_idfirst_namelast_nameemailcity
        1OwenHudsonowen.hudson@icloud.comSan Francisco
        2DouglasMendozadmendoza69@gmail.comAtlanta
        3HenryBrookshbrooks@lakesidecafe.comLos Angeles
        4BrianGrahambgraham@bluecedarhomes.comSeattle

        Mote revisa tu resultado

        Presiona Ejecutar. Cada fila que cumple el objetivo se vuelve una luciérnaga en tu linterna.

        DataFrames

        Cargados como DataFrames de pandas, junto con pd y np.

        customers2,018 filas · 9 columnas
        • customer_idinteger
        • first_namevarchar
        • last_namevarchar
        • emailvarchar
        • cityvarchar
        • statevarchar
        • signup_datedate
        • segmentvarchar
        • referral_sourcevarchar
        Primeras 5 filas de customers
        customer_idfirst_namelast_nameemailcitystatesignup_datesegmentreferral_source
        1OwenHudsonowen.hudson@icloud.comSan FranciscoCA2022-06-02consumersearch
        2DouglasMendozadmendoza69@gmail.comAtlantaGA2022-06-02consumerNaN
        3HenryBrookshbrooks@lakesidecafe.comLos AngelesCA2022-06-04businessNaN
        4BrianGrahambgraham@bluecedarhomes.comSeattleWA2022-06-06businesspinterest
        5KyleJimenezkjimenez27@yahoo.comIndianapolisIN2022-06-07consumerNaN
        orders12,000 filas · 7 columnas
        • order_idinteger
        • customer_idinteger
        • order_datetimestamp
        • statusvarchar
        • channelvarchar
        • shipping_feedecimal
        • coupon_codevarchar
        Primeras 5 filas de orders
        order_idcustomer_idorder_datestatuschannelshipping_feecoupon_code
        10011252023-01-01 20:51:19completedweb0.00NaN
        10021562023-01-02 07:58:46completedweb0.00NaN
        1003222023-01-02 10:25:27completedmarketplace4.99WELCOME10
        1004482023-01-02 11:21:51completedmarketplace4.99WELCOME10
        1005822023-01-02 11:43:36completedweb0.00WELCOME10
        order_items30,338 filas · 6 columnas
        • order_item_idinteger
        • order_idinteger
        • product_idinteger
        • quantityinteger
        • unit_pricedecimal
        • discount_pctdecimal
        Primeras 5 filas de order_items
        order_item_idorder_idproduct_idquantityunit_pricediscount_pct
        11001121931.990.00
        21001154311.990.00
        31002154411.990.00
        410021941149.000.00
        51002193219.990.00
        products120 filas · 8 columnas
        • product_idinteger
        • namevarchar
        • categoryvarchar
        • subcategoryvarchar
        • unit_pricedecimal
        • unit_costdecimal
        • launched_ondate
        • is_activeboolean
        Primeras 5 filas de products
        product_idnamecategorysubcategoryunit_priceunit_costlaunched_onis_active
        101Vale Velvet LoveseatFurnitureSofas1659.00NaN2023-09-11true
        102Alder Oak Coffee TableFurnitureTables919.00503.502024-05-16true
        103Orchard Rattan Dining ChairFurnitureChairs789.00429.872023-05-27true
        104Upland Oak BookcaseFurnitureStorage429.00214.702022-12-20true
        105Avery Leather Bed FrameFurnitureBeds449.00232.702021-08-31true
        returns1,673 filas · 5 columnas
        • return_idinteger
        • order_item_idinteger
        • returned_ondate
        • reasonvarchar
        • refund_amountdecimal
        Primeras 5 filas de returns
        return_idorder_item_idreturned_onreasonrefund_amount
        1142023-01-10damaged83.69
        2422023-01-10wrong_item19.99
        31052023-01-14wrong_item10.99
        4242023-01-16changed_mind26.99
        51262023-01-16late20.99
        employees60 filas · 8 columnas
        • employee_idinteger
        • first_namevarchar
        • last_namevarchar
        • departmentvarchar
        • titlevarchar
        • manager_idinteger
        • hire_datedate
        • salaryinteger
        Primeras 5 filas de employees
        employee_idfirst_namelast_namedepartmenttitlemanager_idhire_datesalary
        1CatherineHaleExecutiveChief Executive OfficerNaN2016-03-01285000
        2RobertKimExecutiveChief Operating Officer12017-01-09235000
        3MeganCollinsSalesHead of Sales12018-04-16172000
        4ChloeGutierrezSalesAccount Executive32020-01-2172000
        5FrankBellSalesAccount Executive32023-05-2173000
        web_sessions40,000 filas · 7 columnas
        • session_idinteger
        • customer_idinteger
        • started_attimestamp
        • devicevarchar
        • sourcevarchar
        • pages_viewedinteger
        • convertedboolean
        Primeras 5 filas de web_sessions
        session_idcustomer_idstarted_atdevicesourcepages_viewedconverted
        1NaN2023-01-01 23:02:24mobilepaid1false
        2182023-01-01 15:07:49desktoppaid1false
        3NaN2023-01-01 16:55:46desktopdirect7false
        4NaN2023-01-01 12:43:28mobileorganic3false
        5NaN2023-01-01 13:06:21mobilesocial2false
        marketing_spend3,276 filas · 3 columnas
        • spend_datedate
        • channelvarchar
        • amountdecimal
        Primeras 5 filas de marketing_spend
        spend_datechannelamount
        2023-01-01paid492.99
        2023-01-01email37.38
        2023-01-01social200.53
        2023-01-02paid709.13
        2023-01-02email64.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() es True para todo NaN, porque NaN nunca es igual a nada. Cuenta los valores desordenados con .notna() en la máscara.
        • head(10) sin sort_values devuelve los diez primeros estados en orden alfabético.

        Elige qué puede ejecutarse en este sitio. Puedes cambiarlo cuando quieras desde "Configurar cookies", al pie de cada página.