La solicitud

De Jordan Reyes, Jefe de Marketing

“Estoy planificando ofertas por tamaño de carrito: una para carritos pequeños, una para medianos y una para los que más gastan. Antes de elegir los cortes, ¿cómo se reparten nuestros pedidos por rangos de precio?”

Tu objetivo

Divide completed["order_value"] en los rangos dados en el código inicial con pd.cut(..., bins=bins, labels=labels). Asigna a result la proporción de pedidos en cada rango, tal como la devuelve .value_counts(sort=False, normalize=True), redondeada a 3 decimales (una Series indexada por rango, con los rangos en orden).

  • Usa el DataFrame orderspendiente
  • Usa el DataFrame order_itemspendiente
  • Muestra exactamente order_value proportionpendiente
Share of orders and share of revenue by order value band
Share of orders and share of revenue by order value band0%10%20%30%40%under $100, Orders: 26.2%under $100, Revenue: 2.3%under $100$100-250, Orders: 21.8%$100-250, Revenue: 6.9%$250-500, Orders: 19.8%$250-500, Revenue: 13.2%$250-500$500-1,000, Orders: 16.7%$500-1,000, Revenue: 21.8%$1,000-2,500, Orders: 12.4%$1,000-2,500, Revenue: 34.5%$1,000-2,500$2,500+, Orders: 3%$2,500+, Revenue: 21.3%Order value bandOrdersRevenue
Share of orders and share of revenue by order value band0%10%20%30%40%under $100, Orders: 26.2%under $100, Revenue: 2.3%under $100$100-250, Orders: 21.8%$100-250, Revenue: 6.9%$250-500, Orders: 19.8%$250-500, Revenue: 13.2%$500-1,000, Orders: 16.7%$500-1,000, Revenue: 21.8%$500-1,000$1,000-2,500, Orders: 12.4%$1,000-2,500, Revenue: 34.5%$2,500+, Orders: 3%$2,500+, Revenue: 21.3%Order value bandOrdersRevenue

Small baskets are a quarter of all orders and 2% of revenue. Orders above $1,000 are 15% of orders and more than half of revenue.

Ver los números
Order value bandOrdersRevenue
under $10026.2%2.3%
$100-25021.8%6.9%
$250-50019.8%13.2%
$500-1,00016.7%21.8%
$1,000-2,50012.4%34.5%
$2,500+3%21.3%

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

    La forma antes que el resumen

    En el capítulo anterior viste que el pedido medio ($543) es el doble de la mediana ($269). Esa brecha te dice que la columna está sesgada a la derecha, pero no cómo se ve su forma. Una distribución responde “¿cuántos valores hay de cada tamaño?”, y para verla agrupas los valores en tramos, llamados intervalos o rangos, y cuentas cada uno.

    pandas mide directamente la asimetría:

    completed["order_value"].skew()   # 3.95

    Un sesgo de 0 significa simétrico. Por encima de 1 está fuertemente sesgado a la derecha: la mayoría de los valores son pequeños, con una cola larga de valores grandes. Los valores de pedido están casi en 4.

    Cortar valores en rangos

    pd.cut asigna cada valor a un rango que tú defines:

    bins = [0, 100, 250, 500, 1000, 2500, float("inf")]
    labels = ["under $100", "$100-250", "$250-500", "$500-1,000", "$1,000-2,500", "$2,500+"]
    bands = pd.cut(completed["order_value"], bins=bins, labels=labels)
    bands.value_counts(sort=False)

    Cada rango incluye su borde derecho: un pedido de exactamente $100.00 cae en “under $100”. Un valor fuera de todos los rangos (aquí los 4 pedidos de $0 o menos) recibe NaN y queda fuera de los conteos. sort=False mantiene los rangos en su orden natural en lugar de ordenarlos por conteo.

    Rangos desiguales a propósito

    Los rangos de aquí se ensanchan a medida que crecen los valores: de $100, $150, $250, $500 y $1,500 de ancho. En una columna sesgada ese es el punto. Rangos iguales de $500 pondrían dos tercios de los pedidos en el primer rango y dejarían los rangos altos con un puñado cada uno. Rangos más anchos donde los datos escasean mantienen cada rango con sentido.

    Pedidos frente a ingresos

    El gráfico pone dos distribuciones lado a lado. Los pedidos se acumulan a la izquierda: una cuarta parte está por debajo de $100. Los ingresos se acumulan a la derecha: esos carritos pequeños aportan el 2% de las ventas, mientras que los pedidos de más de $1,000 (15% de los pedidos) aportan más de la mitad. Las dos cosas son ciertas y responden preguntas distintas. “¿Dónde están la mayoría de los clientes?” es la vista de pedidos. “¿Dónde está el dinero?” es la vista de ingresos. Un buen analista le muestra ambas a Jordan antes de que fije los umbrales de las ofertas.

    Errores comunes

    • Olvidar los bordes. pd.cut incluye el borde derecho y excluye el izquierdo. Un primer borde de 0 descarta los valores cero y negativos; revisa cuántos NaN obtienes con bands.isna().sum().
    • Ordenar por conteo. value_counts() pone primero el rango más grande por defecto. En los valores de pedido los rangos casualmente se achican en orden, así que no lo notarías; en la mayoría de las columnas desordena la distribución. Pon sort=False y los rangos conservan su propio orden.
    • Rangos de igual ancho en datos sesgados. La mayoría de los rangos queda casi vacía y uno concentra casi todos los datos. Usa rangos que coincidan con cómo habla el negocio, o cuantiles con pd.qcut.

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