1. Faro

Nivel 9 · Desafío final: ¿es el canal o es el cliente?

La solicitud

De Catherine Hale, Directora General

“La junta no deja de preguntar si deberíamos empujar a los clientes hacia un canal de venta porque sus cestas son más grandes. ¿El tamaño de la cesta tiene de verdad que ver con el canal, o con quién es el cliente? Cifras, una imagen y una frase clara.”

Tu objetivo

Paso 1 de 4. Asigna a result un DataFrame con una fila por canal y las columnas channel, business y consumer: el valor de pedido mediano de ese canal y segmento, redondeado a 2, ordenado por channel de la A a la Z. Dibújalo como un heatmap anotado.

  • Usa el DataFrame customerspendiente
  • Usa el DataFrame orderspendiente
  • Muestra exactamente channel business consumerpendiente

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.

        Paso 4 · 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

          Dividir por el segundo factor

          La junta compara canales. Pero la cesta media de un canal depende de quién compra allí. Si los clientes business prefirieran un canal, ese canal parecería mejor por una razón que no tiene nada que ver con el canal en sí. La comprobación es dividir por el segundo factor y ver dónde están realmente las diferencias.

          Un pivot con canales en vertical y segmentos en horizontal hace exactamente eso, y un mapa de calor lo hace legible:

          grid = per_order.pivot_table(index="channel", columns="segment", values="value", aggfunc="median")
          sns.heatmap(grid, annot=True, fmt=",.0f", cmap="Blues", cbar_kws={"label": "Median order (USD)"})

          Usa una paleta secuencial como Blues para valores todos positivos, clara para los bajos y oscura para los altos. Reserva la divergente coolwarm para números con signo, como las correlaciones.

          Dispersión, no solo el centro

          Una mediana por celda puede ocultar dispersiones muy distintas, así que dibuja también las cajas. hue="segment" divide en dos la caja de cada canal:

          sns.boxplot(data=per_order, x="channel", y="value", hue="segment", order=order, showfliers=False)

          showfliers=False oculta los puntos atípicos para que las cajas no queden aplastadas por unos pocos pedidos enormes. Dilo en la etiqueta del eje, ya que estás ocultando datos de la imagen (no de las cifras).

          Un panel en seaborn

          Las funciones de seaborn aceptan un argumento ax=, así que una cuadrícula de plt.subplots contiene gráficos de seaborn con tanta facilidad como los de matplotlib:

          fig, axs = plt.subplots(1, 2, figsize=(13, 4.5))
          sns.heatmap(grid, annot=True, fmt=",.0f", cmap="Blues", ax=axs[0])
          sns.boxplot(data=per_order, x="channel", y="value", hue="segment", showfliers=False, ax=axs[1])
          plt.tight_layout()

          Exportar y redactar

          Tus compañeros reciben la tabla como un archivo: to_csv(path, index=False) escribe CSV, to_excel una hoja de Excel (necesita el paquete openpyxl), to_parquet un archivo compacto y tipado para datos grandes. Sin ruta, to_csv devuelve el texto, lo cual es práctico para comprobar lo que escribirías.

          Luego la frase. Las medianas por canal van de $249 en marketplace a $263 en web, una diferencia de aproximadamente el 5 %. La mediana de un pedido business es unas 3,8 veces la de un pedido consumer. Qué: el canal casi no importa. Cuánto: $249 a $263, frente a 3,8 veces. Para qué: segmenta por segmento.

          Errores comunes

          • Comparar canales sin dividir por segmento, y atribuir al canal el mérito de sus clientes.
          • Una paleta divergente para valores todos positivos, que sugiere un punto medio con significado que no existe.
          • Escribir las cifras en la conclusión a mano en lugar de darles formato desde los datos.

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