1. Lighthouse

Level 8 · Two weeks before Black Friday in NumPy

The request

From Megan Collins, Head of Sales

“I have daily orders and revenue for November 17 to 30 as two lists. I need the average order value per day, how many orders came in the second week, how each day of week two compares with the same weekday of week one, and the order counts of our really busy days, over 40.”

Your goal

Turn the lists into NumPy arrays. Set result to a dictionary with keys 'aov' (revenue / orders for each day, rounded to 2, as a list of 14 floats), 'week2_orders' (sum of orders for the last 7 days, an int), 'vs_last_week' (orders of days 8–14 minus orders of days 1–7, day by day, as a list of 7 ints) and 'busy_days' (the order counts greater than 40, in date order, as a list).

  • Store a dict in resultnot done yet

Your code

Python

Loading the editor…

    ResultPress Run to see yours

    Mote checks your result

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

    The lesson

    Arrays do the maths element by element

    NumPy is the number-crunching library underneath pandas, already loaded here as np. Its core object is the array: a list of values of one type that supports maths on all of them at once.

    o = np.array([23, 24, 17, 22, 22, 18, 26, 20, 22, 15, 24, 56, 51, 58])
    r = np.array([10937, 16395, 9826, ...])
    
    r / o        # 14 averages: 475.52, 683.12, 578.0, ...
    o * 2        # every count doubled
    o + 5        # every count plus 5

    Operations between two arrays of the same length pair the values up by position. That is why r / o gives one average order value per day without a loop. Plain lists behave differently: orders * 2 repeats the list, and revenue / orders is a TypeError.

    The averages tell their own story. Black Friday (November 28, the 12th value) had the most orders but an average of only $306.59, below most ordinary days. Almost half of that day’s orders used the 25% Black Friday coupon, which pulls the basket value down.

    Slicing a week

    Arrays slice like lists. Positions start at 0, and the end of a slice is excluded:

    o[:7]           # days 1-7, the week of November 17
    o[7:]           # days 8-14, the week of November 24
    o[7:].sum()     # 246
    o[7:] - o[:7]   # [-3, -2, -2, 2, 34, 33, 32]

    Because both slices have 7 values, subtracting them compares Monday with Monday, Tuesday with Tuesday, and so on. .sum() returns a NumPy integer; int(...) turns it into a plain Python int.

    Boolean indexing

    A comparison on an array gives an array of True and False, one per value:

    o > 40          # [False, False, ..., True, True, True]
    o[o > 40]       # [56, 51, 58]

    Putting that True/False array inside the brackets keeps only the values where it is True. This is called boolean indexing, and it is exactly how filtering a DataFrame works. Conditions can be combined with & (and) and | (or), each wrapped in parentheses: o[(o > 20) & (o < 30)] keeps the ordinary busy days and drops both the quiet ones and the Black Friday peak. The result is always a new, shorter array; the original o keeps all 14 values.

    Common mistakes

    • Doing arithmetic on the lists instead of arrays.
    • Slicing o[8:] for the second week, which skips its Monday. Position 7 is the 8th day.
    • Writing o > 40 and expecting the values back; you get True/False. Put it inside o[...].
    • Returning arrays where lists are asked for. .tolist() converts them.

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