The request

From Jordan Reyes, Head of Marketing
Your goal
From booked (booked orders, built in the starter), set result to a DataFrame with one row per year and the columns year, new_orders (orders that are the customer's first booked order), returning_orders (all other booked orders) and new_share_pct (new_orders * 100 / all booked orders that year, rounded to 2). A customer's first order is the booked order with their lowest order_id. Sort by year.
- Show exactly
yearnew_ordersreturning_ordersnew_share_pctnot done yet - 3 rows, sorted as askednot done yet
Your code
Loading the editor…
Reference solution
Mote checks your result
Press Run. Each row that matches the goal becomes a firefly in your lantern.
What Jordan gets, and why
The lesson
Two kinds of order
Every order is either a customer’s first order (an acquisition) or a repeat order from a customer the store already has. Marketing teams split them because they are bought differently: first orders cost ad money, repeat orders mostly come from product quality, email and habit.
At Harbor & Pine the split is lopsided. In 2025 there were 4,409 booked orders, and only 641 of them were somebody’s first:
# year new_orders returning_orders new_share_pct
# 2023 574 2398 19.31
# 2024 525 3247 13.92
# 2025 641 3768 14.54
About six in seven orders come from customers who had bought before.
Which order is “first”
The definition needs two decisions. Which statuses count? Only booked orders (completed or
refunded). A customer whose first attempt was cancelled was not acquired that day; they were
acquired when they first paid. How do you break ties? Order ids grow with time, so the lowest
booked order_id per customer is their first order. Using the minimum order_date instead works
almost everywhere, but one customer placed three orders at the same second in 2024, and a
date-based flag counts all three as “first”.
In pandas, groupby(...).transform("min") returns the group’s minimum on every row of the group,
so a single comparison marks the first order:
first_id = booked.groupby("customer_id")["order_id"].transform("min")
booked["is_new"] = booked["order_id"] == first_id
The first year of data lies
2023 shows 19.31% new orders, well above the later years. Part of that is real growth, but part is left-censoring: the data starts on 2023-01-01, so a loyal customer who had been buying since 2022 shows up in 2023 with a “first order”. 152 of the 574 customers counted as new in 2023 had signed up before 2023. Whenever the window starts, the first period overstates acquisition. Report it with a note, or leave it out of trend lines.
Common mistakes
- Counting new customers from
signup_date. Signing up is not buying. 278 customers have no booked order at all (247 never placed one). - Using every status. Cancelled and pending orders inflate both counts and move the first order to a date when nothing was paid.
- Reading the share as growth. A falling new share can mean acquisition slowed or that repeat buying grew faster. Look at both counts, not only the percentage.
Interview note
“How would you define a new customer?” has no single right answer, which is why it is asked. Say what counts as an order, how you find the first one, and what the start of the data does to the first period. That is the answer.
Lantern lit!
Practised: new customersreturning customersfirst ordergroupbytransform
- Solved
- No hints
- First run
