1. Faro

Nivel 1 · Añade nombres de producto a las líneas de pedido

¿Es nuevo para ti? Lee primero el concepto: Qué le hace un merge a tu número de filas

La solicitud

De Angela Rivera, Directora de Atención al Cliente

“Nuestros agentes ven IDs de producto en las líneas de pedido y tienen que buscar cada uno. ¿Puedes darme las líneas de nuestros primeros diez pedidos, del 1001 al 1010, con el nombre y la categoría del producto?”

Tu objetivo

Asigna a result un DataFrame con una fila por cada línea de pedido de los pedidos 1001 a 1010 (ambos incluidos): columnas order_item_id, order_id, name, category, quantity (name y category vienen de products, unidas por product_id), ordenado por order_item_id ascendente, con el índice reiniciado.

  • Usa el DataFrame productspendiente
  • Usa el DataFrame order_itemspendiente
  • Muestra exactamente order_item_id order_id name category quantitypendiente

Tu código

Python

Cargando el editor…

    ResultadoVista previa de products · presiona Ejecutar para ver el tuyo
    Vista previa de products
    product_idnamecategorysubcategoryunit_price
    101Vale Velvet LoveseatFurnitureSofas1659.00
    102Alder Oak Coffee TableFurnitureTables919.00
    103Orchard Rattan Dining ChairFurnitureChairs789.00
    104Upland Oak BookcaseFurnitureStorage429.00

    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.

    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
    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
    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
    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

    Por qué las tablas están separadas

    order_items guarda un product_id en cada línea en lugar del nombre, la categoría y el precio del producto. Es a propósito: los detalles del producto viven en un solo sitio, products, así que renombrar un producto significa cambiar una fila, no 30.000. El coste es que tienes que unir las tablas de nuevo (hacer un join) cuando necesitas ambas.

    merge

    order_items.merge(products, on="product_id")

    Para cada línea de pedido, pandas busca la fila de producto con el mismo product_id y pone sus columnas una al lado de otra. La columna por la que emparejas es la clave. Si la clave se llama distinto en las dos tablas, usa left_on= y right_on=. Por ejemplo, el manager_id de cada empleado apunta al employee_id de otro empleado, así que esto pone a cada empleado junto a los datos de su jefe:

    employees.merge(employees, left_on="manager_id", right_on="employee_id", suffixes=("", "_manager"))

    Eso da 59 filas, no 60: el CEO no tiene jefe, así que el merge inner deja fuera esa fila.

    El argumento how= decide qué pasa con las filas sin pareja:

    how conserva
    "inner" (por defecto) solo las filas con pareja en ambas tablas
    "left" todas las filas de la tabla izquierda; NaN donde la derecha no tiene pareja
    "right" todas las filas de la tabla derecha
    "outer" todo de ambas

    Aquí cada línea de pedido tiene un producto válido, así que inner y left dan el mismo resultado. Escribe how= de forma explícita de todos modos; le dice al lector que lo pensaste.

    Nombres de columna repetidos

    Ambas tablas tienen una columna unit_price, y significan cosas distintas: el precio pagado en la línea frente al precio de lista de hoy. pandas conserva las dos y añade suffixes, unit_price_x y unit_price_y. Esos nombres son fáciles de confundir, así que pon los tuyos:

    order_items.merge(products, on="product_id", suffixes=("_paid", "_list"))

    O selecciona solo las columnas que necesitas de la tabla derecha antes de unir, lo que además mantiene el resultado estrecho:

    order_items.merge(products[["product_id", "name", "category"]], on="product_id")

    Comprueba el número de filas

    El hábito más útil con los merges: comparar el número de filas antes y después.

    len(order_items)                                   # lines before
    len(order_items.merge(products, on="product_id"))  # should be the same

    Cada línea tiene exactamente un producto, así que el número no debe cambiar. Si creció, la tabla derecha tenía claves duplicadas y algunas líneas se copiaron. Si se redujo, algunas líneas no tenían pareja y un join inner las descartó. Verás ambos problemas más adelante en este capítulo.

    pandas puede comprobarlo por ti. validate="many_to_one" dice “muchas líneas pueden compartir un producto, pero cada producto aparece una vez en products”, y lanza un error si no es así:

    order_items.merge(products, on="product_id", how="inner", validate="many_to_one")

    Otras opciones son "one_to_one" y "one_to_many". Añadir validate no cuesta nada y convierte un error silencioso en uno ruidoso.

    Errores comunes

    • Hacer merge sin on=. pandas entonces une por todas las columnas con el mismo nombre en ambas tablas, aquí product_id y unit_price, y la mayoría de las líneas no encuentran pareja porque los precios cambiaron.
    • Usar unit_price_x más tarde sin recordar de qué tabla venía.
    • No comprobar el número de filas después de un merge.

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