1. Faro

Nivel 1 · Pedidos por canal y estado, en una cuadrícula

¿Es nuevo para ti? Lee primero el concepto: Tablas largas para calcular, cuadrículas anchas para leer

La solicitud

De Megan Collins, Directora de Ventas

“Para la reunión de ventas del lunes quiero una cuadrícula pequeña: nuestros tres canales en el lateral, cada estado de pedido arriba, y el número de pedidos en cada celda.”

Tu objetivo

Asigna a result un DataFrame con una fila por canal y las columnas channel, cancelled, completed, pending, refunded, donde cada columna de estado contiene el número de pedidos con ese canal y estado (un int, 0 cuando no hay ninguno). Ordena por channel de la A a la Z.

  • Usa el DataFrame orderspendiente
  • Muestra exactamente channel cancelled completed pending refundedpendiente
  • 3 filas, ordenadas como se pidependiente

Tu código

Python

Cargando el editor…

    ResultadoVista previa de orders · presiona Ejecutar para ver el tuyo
    Vista previa de orders
    order_idcustomer_idorder_datestatuschannel
    10011252023-01-01 20:51:19completedweb
    10021562023-01-02 07:58:46completedweb
    1003222023-01-02 10:25:27completedmarketplace
    1004482023-01-02 11:21:51completedmarketplace

    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.

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

    Tablas largas y cuadrículas anchas

    Un groupby con dos claves te da una tabla larga: una fila por combinación.

    orders.groupby(["channel", "status"]).size()
    # channel      status
    # app          cancelled     265
    #              completed    3885
    #              pending        50
    #              refunded      120
    # marketplace  cancelled     108
    # ...                       (12 rows)

    Todos los números están ahí, pero es difícil compararlos entre canales. Una cuadrícula ancha pone una clave en el lateral y la otra arriba, de modo que cada celda es una combinación. Eso es lo que la gente entiende por tabla dinámica en una hoja de cálculo, y pandas tiene la misma herramienta: pivot_table.

    Cuatro argumentos, cuatro preguntas

    Cada argumento responde una pregunta sobre la cuadrícula que quieres:

    orders.pivot_table(
        values="order_id",     # WHAT do I measure?
        index="channel",       # what goes DOWN the side (one row each)?
        columns="status",      # what goes ACROSS the top (one column each)?
        aggfunc="count",       # WHICH operation combines the rows in a cell?
    )
    • values es la columna que agregas. Para contar filas, lo más claro es una columna de ID sin huecos.
    • index se convierte en las etiquetas de fila, ordenadas de la A a la Z; columns en las etiquetas de columna, también ordenadas.
    • aggfunc es el cálculo: "count", "sum", "mean", "median", "max", "nunique". aggfunc="size" cuenta filas sin necesitar values en absoluto.

    Si omites columns obtienes un resumen unidimensional: una fila por canal, una columna.

    El resultado tiene channel como índice y los estados como columnas. Cuando compruebas la tabla o la exportas, el nombre del índice channel viaja como primera columna.

    Celdas vacías y fill_value

    Cuando una combinación nunca ocurre, la celda está vacía, y pandas la muestra como NaN. Productos por categoría y marca de activo es un buen ejemplo: todos los productos de Lighting siguen activos.

    products.pivot_table(index="category", columns="is_active",
                         values="product_id", aggfunc="count")
    # is_active  False  True
    # category
    # Decor        3.0   17.0
    # ...
    # Lighting     NaN   20.0

    El NaN además convierte los recuentos en floats (3.0, 17.0). Para un recuento, “sin filas” significa 0, así que pasa fill_value=0: la celda vacía pasa a ser 0 y los recuentos siguen siendo números enteros.

    products.pivot_table(index="category", columns="is_active",
                         values="product_id", aggfunc="count", fill_value=0)
    # Lighting       0    20

    Rellena con 0 solo cuando cero es la verdad. Para un precio medio en una celda sin productos, 0 sería una mentira; déjalo como NaN.

    ¿pivot_table o groupby?

    Ambos calculan los mismos números. Elige según la forma que necesites después:

    • pivot_table cuando el resultado es un informe: filas × columnas para que una persona lea, exporte o grafique en dos dimensiones. En la tabla de pedidos completa, los pedidos completados son 5.367 para web, 3.885 para app y 1.597 para marketplace, uno junto al otro en una sola columna.
    • groupby cuando el resultado es un cálculo: un valor por grupo que vas a filtrar, unir o pasar al siguiente paso.

    Errores comunes

    • Omitir aggfunc. El valor por defecto es "mean", que promedia valores de order_id: números, pero sin sentido.
    • Intercambiar index y columns, lo que da los estados como filas y los canales arriba.
    • Contar una columna que tiene valores ausentes. "count" omite los NaN, así que usa una columna de ID o aggfunc="size".
    • Rellenar con 0 cuando el agregado es una media o una tasa: una celda vacía es desconocida, no cero.

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