We're sorry but this app doesn't work properly without JavaScript enabled. Please enable it to continue.

This lesson's interactive features are locked, please to keep using them

Ordered Funnels

Our funnel approach from before has a flaw: it doesn't enforce order. A user could have a purchase event before a signup event (from a different session, a data bug, etc.).

Sometimes you want a strict ordered funnel, to only count steps that happened in the expected sequence:

def user_completed_ordered_funnel(user_events, steps):
    user_events = user_events.sort_values("timestamp")
    event_list = user_events["event_type"].tolist()

    last_idx = -1
    completed = []
    for step in steps:
        # Search for each step after the position of the previous step,
        # so repeated events are handled correctly.
        if step in event_list[last_idx + 1 :]:
            last_idx = event_list.index(step, last_idx + 1)
            completed.append(step)
        else:
            break
    return completed

Apply this function per user with groupby() and a lambda to get the ordered funnel steps each user completed:

steps = ["page_view", "signup", "lesson_submit", "purchase"]
user_funnels = events.groupby("user_id").apply(
    lambda df: user_completed_ordered_funnel(df, steps)
)

Which prints something like:

user_id
101    [page_view, signup, lesson_submit, purchase]
202              [page_view, signup, lesson_submit]
303                             [page_view, signup]
404                                     [page_view]
505    [page_view, signup, lesson_submit, purchase]
dtype: object

Why Order Matters

Say you're trying to test the conversion rate of a specific landing page, perhaps one that has traffic coming from a specific influencer partner.

If you use an unordered funnel, you'll be counting signups that come from your homepage as well as signups that come from the specific landing page. If you use an event or property specific to that landing page (like path: "/pewdiepie-lander") and an ordered funnel, your results will be specific to that landing page.

If your ordered funnel numbers are significantly lower than your unordered numbers, it means users are taking unexpected paths – which is worth investigating.

Assignment

SnackStack's growth team wants to know how many users make it through onboarding in the right order: open the app, pair a device, start a recipe, then reorder supplies.

Complete the ordered_funnel_counts function. It accepts an events DataFrame with user_id, event_type, and timestamp columns plus an ordered steps list, and returns a Series of how many users reached each step in order.