1. Lighthouse

Level 3 · What a customer has been worth

The request

From Laura Bennett, Head of Finance

“For the budget I need lifetime value by the year we acquired the customer. How much net revenue has each cohort brought in so far, per customer? Someone told me our newer customers are worth far less, and I'd like to know if that's true.”

Your goal

From booked (booked orders with revenue = net sales minus refunds, built in the starter), set result to a DataFrame with one row per acquisition year and the columns first_year (year of the customer's first booked order), customers (number of customers acquired that year), net_revenue (their total revenue over 2023–2025, rounded to 2) and ltv (net_revenue / customers, rounded to 2, computed from the unrounded total). Sort by first_year.

  • Use the orders DataFramenot done yet
  • Use the order_items DataFramenot done yet
  • Show exactly first_year customers net_revenue ltvnot done yet

Your code

Python

Loading the editor…

    ResultPreview of orders · press Run to see yours
    Preview of 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 checks your result

    Press Run. Each row that matches the goal becomes a firefly in your lantern.

    DataFrames

    Loaded for you as pandas DataFrames, plus pd and np.

    orders12,000 rows · 7 columns
    • order_idinteger
    • customer_idinteger
    • order_datetimestamp
    • statusvarchar
    • channelvarchar
    • shipping_feedecimal
    • coupon_codevarchar
    First 5 rows of 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 rows · 6 columns
    • order_item_idinteger
    • order_idinteger
    • product_idinteger
    • quantityinteger
    • unit_pricedecimal
    • discount_pctdecimal
    First 5 rows of 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 rows · 5 columns
    • return_idinteger
    • order_item_idinteger
    • returned_ondate
    • reasonvarchar
    • refund_amountdecimal
    First 5 rows of 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
    customers2,018 rows · 9 columns
    • customer_idinteger
    • first_namevarchar
    • last_namevarchar
    • emailvarchar
    • cityvarchar
    • statevarchar
    • signup_datedate
    • segmentvarchar
    • referral_sourcevarchar
    First 5 rows of 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 rows · 8 columns
    • product_idinteger
    • namevarchar
    • categoryvarchar
    • subcategoryvarchar
    • unit_pricedecimal
    • unit_costdecimal
    • launched_ondate
    • is_activeboolean
    First 5 rows of 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
    employees60 rows · 8 columns
    • employee_idinteger
    • first_namevarchar
    • last_namevarchar
    • departmentvarchar
    • titlevarchar
    • manager_idinteger
    • hire_datedate
    • salaryinteger
    First 5 rows of 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 rows · 7 columns
    • session_idinteger
    • customer_idinteger
    • started_attimestamp
    • devicevarchar
    • sourcevarchar
    • pages_viewedinteger
    • convertedboolean
    First 5 rows of 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 rows · 3 columns
    • spend_datedate
    • channelvarchar
    • amountdecimal
    First 5 rows of marketing_spend
    spend_datechannelamount
    2023-01-01paid492.99
    2023-01-01email37.38
    2023-01-01social200.53
    2023-01-02paid709.13
    2023-01-02email64.13

    The lesson

    Lifetime value, looking back

    Customer lifetime value (LTV) is the revenue (or margin) a customer brings in over their whole relationship with the business. The simplest honest version is historic LTV: take a group of customers, add up everything they have actually spent so far, and divide by how many there are. No forecasts, no assumptions.

    The natural group is the acquisition cohort: everyone whose first booked order fell in the same year. Here revenue is net revenue (discounted line value minus refunds, no shipping), counted over everything the data holds, 2023 to 2025.

    #   first_year  customers  net_revenue      ltv
    # 0       2023        574   3564271.36  6209.53
    # 1       2024        525   1401056.50  2668.68
    # 2       2025        641    721955.12  1126.30

    Why young cohorts always look worse

    The 2023 cohort looks five times more valuable than the 2025 cohort. It isn’t, or at least this table can’t say so. A customer acquired in January 2023 had three years to keep ordering; one acquired in November 2025 had a few weeks. Historic LTV grows with cohort age, so comparing cohorts of different ages mostly measures time.

    The fix is an equal window: revenue in each customer’s first 365 days after their first order. That gives $3,605.08 for 2023 and $2,142.10 for 2024. The 2025 cohort cannot be measured yet, because most of its customers have not had a full year. A real drop is still visible (2024 customers spent less in their first year), but it is about 40%, not the 57% the to-date numbers suggest.

    And the first cohort is special

    The 2023 number has its own bias. The data starts on 2023-01-01, so 152 of the 574 customers “acquired” in 2023 had signed up before that and were already regulars. Their first year in the data is not their first year as customers, which flatters the 2023 cohort.

    Common mistakes

    • Counting rows instead of customers. size counts orders. Use nunique on customer_id.
    • Using gross sales. Refunds and discounts are money the store never kept. LTV in revenue terms should be net revenue, and the margin version (next level) is better still.
    • One number for everyone. A single all-time LTV mixes old and young cohorts and changes every month even if nothing about the customers changes.

    Interview note

    “Our LTV is falling for newer cohorts, what do you check first?” The expected answer: whether the cohorts have been observed for the same length of time. Then compare an equal window, such as the first 12 months.

    Pick what may run on this site. You can change this any time from "Cookie settings" at the bottom of every page.