NumPy: Arrays and Vectorized Calculations
Learning Objectives
- You can create a NumPy array from a list of numbers.
- You can use array methods such as
.sum(),.mean(),.min(), and.max(). - You can explain elementwise arithmetic and boolean masks.
- You can describe why NumPy is useful preparation for pandas.
NumPy is a third-party library for working with arrays of numbers. An array is a collection of values that NumPy can operate on efficiently.
import numpy as np
minutes = np.array([45, 30, 60])print(minutes.sum())print(minutes.mean())print(minutes.min())print(minutes.max())This prints the total, average, smallest value, and largest value. You could calculate all four with loops, and earlier in the course you did. NumPy gives the collection itself methods that express common numeric operations directly.
Array summary
0 / 5 points
What does this print?
import numpy as npminutes = np.array([10, 20, 30])print(minutes.sum())print(minutes.min())print(minutes.max())Lists and Arrays Are Different Types
A NumPy array can be created from a list, but it is not a list:
import numpy as np
values = [10, 20, 30]array = np.array(values)
print(type(values))print(type(array))This distinction matters because the same operator can mean different things:
print(values * 2)print(array * 2)The list version repeats the list. The array version doubles each value. Neither behavior is wrong; they are different types with different rules.
This is one reason to inspect types when learning a library. A printed array may look list-like, but the operations are NumPy operations.
Elementwise Operations
The first surprising thing about arrays is that arithmetic happens element by element:
import numpy as np
minutes = np.array([45, 30, 60])double_minutes = minutes * 2
print(double_minutes)This prints an array containing 90, 60, and 120. The multiplication was applied to each value in the array.
This is called vectorized calculation. Instead of writing:
result = []for m in minutes: result.append(m * 2)you describe the operation over the whole array:
result = minutes * 2The loop still exists inside NumPy. You are using a higher-level operation.
Elementwise result
0 / 5 points
What is the idea behind np.array([1, 2, 3]) * 10?
Worked Example: From Loop to Array
Suppose the study log has the minutes from one week:
minutes = [45, 30, 60, 25]Using the loop style from Making Decisions and Repeating Work and Summarizing Your Data, doubling each value for a “what if I studied twice as long?” calculation would look like this:
double_minutes = []for m in minutes: double_minutes.append(m * 2)
print(double_minutes)The output is:
[90, 60, 120, 50]The loop version is explicit. You can see the result list start empty, one value at a time, and end with four values. That explicitness is why the course taught this style first.
The NumPy version starts by converting the list into an array:
import numpy as np
minutes_array = np.array(minutes)double_minutes = minutes_array * 2
print(double_minutes)The output is similar but not identical:
[ 90 60 120 50]There are no commas because NumPy prints arrays in its own style. More importantly, double_minutes is now a NumPy array, not a Python list.
The conceptual change is this: in the loop version, you say how to visit each item. In the array version, you say what operation applies to the collection. Both are programming. The array version is shorter because NumPy already knows how to walk over an array and apply an operation to each element.
This is the bridge to pandas. A pandas column behaves more like the NumPy version than the loop version:
df["minutes"] * 2That expression means “double every value in the minutes column.” You will not usually store doubled study minutes in the project, but the pattern is the same as filters, totals, and date comparisons.
Boolean Masks
Comparisons also happen element by element:
import numpy as np
minutes = np.array([10, 45, 90, 25])long_mask = minutes >= 45
print(long_mask)The result is an array of Boolean values:
[False True True False]This Boolean array can be used as a mask:
long_minutes = minutes[long_mask]print(long_minutes)Now the result contains only 45 and 90.
The pattern is:
- create an array,
- compare it to get a Boolean mask,
- use the mask to select matching values.
If the rest of your program expects a plain Python list instead of a NumPy array, convert the result with .tolist() at the boundary:
long_list = long_minutes.tolist().tolist() converts NumPy scalar values inside the array to ordinary Python values too. That matters when the result will later be passed to tools such as json.dumps.
The next exercise sequence changes context to game scores. First you will scale every score and return an ordinary list; then you will use a Boolean mask to count scores at or above a threshold. The NumPy ideas are the same even though the data no longer comes from the study log.
Mask Shape Has to Match
A mask works because it has one Boolean value for each value in the array:
minutes = np.array([10, 45, 90, 25])mask = minutes >= 45There are four minute values and four Boolean values. The first Boolean decides whether the first value is included, the second Boolean decides whether the second value is included, and so on.
That is why this idea transfers so naturally to pandas. In the next chapter, you will meet DataFrames, which are pandas tables. A DataFrame filter has one Boolean value for each row. Each Boolean decides whether that row stays in the filtered table.
If the mask is the wrong length, selection cannot make sense. NumPy and pandas will complain because they cannot line up the yes/no decisions with the data.
Filtering Large Orders
Suppose an online shop needs to find orders whose totals reach a chosen minimum. A small helper can use the same NumPy pattern:
import numpy as np
def large_orders(order_totals, minimum): values = np.array(order_totals) return values[values >= minimum]
print(large_orders([12, 75, 120, 30], 50))This returns a NumPy array containing 75 and 120. If the rest of the shop program expects a regular Python list, convert at the boundary:
return values[values >= minimum].tolist()That boundary habit matters. A NumPy array and a Python list look similar when printed, but they are not the same type.
Long sessions with NumPy
0 / 10 points
Define two functions:
weekly_total(minutes)returns the sum of the numbers inminutes.long_sessions(minutes, threshold)returns a regular Python list containing the values inminutesthat are greater than or equal tothreshold.
Use NumPy arrays inside the functions. Convert the filtered array with .tolist() so the returned list contains ordinary Python values and can be serialized with json.dumps.
If minutes is empty, weekly_total(minutes) should return 0. If no values meet the threshold, long_sessions(minutes, threshold) should return []. Do not ask for user input and do not print inside the functions.
Common Mistake: Expecting List Behavior
Because arrays can be created from lists, it is easy to expect all list habits to carry over. Some do. Many do not.
For example, adding two lists joins them:
a = [10, 20]b = [1, 2]print(a + b)This prints:
[10, 20, 1, 2]Adding two arrays adds matching positions:
import numpy as np
a = np.array([10, 20])b = np.array([1, 2])print(a + b)This prints:
[11 22]Again, neither behavior is wrong. The operator belongs to the type. This is why the tiny inspection habit matters:
print(type(a))print(a)When a result surprises you, first ask what type you are working with. The same spelling can mean different operations for different types.
Empty Arrays and Summary Meaning
NumPy can summarize empty arrays, but not every summary has a sensible answer:
import numpy as np
values = np.array([])print(values.sum())print(values.mean())The sum of an empty collection is 0.0, which is often useful. The mean of an empty collection is not a real number, because there is no count to divide by. NumPy will warn and produce a special “not a number” value.
This is the same design issue you met earlier with averages. The library has behavior, but your function still needs a contract. If your helper returns an average, decide what happens when there are no values. Returning None may be clearer than returning a NumPy special value to the rest of your project.
Reading NumPy Output Without Overreacting
NumPy output can look a little unfamiliar at first:
[45 30 60]The missing commas do not mean the values are joined into one string. It is just NumPy’s display style for arrays. The array still contains three separate numbers.
The same is true for Boolean masks:
[False True True False]There are four Boolean values here. NumPy lines them up with spaces. When you are learning, read the output slowly and compare it to the input:
minutes = np.array([10, 45, 90, 25])mask = minutes >= 45The first value, 10, does not meet the condition, so the first mask value is False. The second value, 45, does meet it, so the second mask value is True. The same relationship continues for the rest of the array.
This kind of manual checking is still useful. A library can perform the operation quickly, but you can verify whether the operation matches your intent by tracing a tiny case. If a mask is supposed to mark long sessions, use four values where you can predict every True and False by inspection.
That is the same verification skill from earlier parts, now applied to library-shaped output.
Why NumPy Before pandas?
Pandas uses many NumPy ideas:
- operations over whole columns,
- Boolean masks for filtering rows,
- summary methods such as
.sum()and.mean(), - and the idea that data has a shape.
You will not become a NumPy expert in this chapter. The goal is smaller: when pandas later lets you write df["minutes"] >= 45, that expression should feel familiar. It is the same idea as minutes >= 45, applied to a table column.
Practice that idea once more with a helper that filters first and then summarizes.
Average long sessions with NumPy
0 / 10 points
Define a function named average_long_session(minutes, threshold).
minutes is a list of session lengths. Use a NumPy array and a Boolean mask to select the values that are greater than or equal to threshold.
Return the average of the selected values, using NumPy’s .mean() method. If no values match, return None.
Example calls and return values:
average_long_session([10, 45, 90, 25], 45) -> 67.5average_long_session([10, 20], 45) -> NoneDo not ask for user input and do not print inside the function.
Check Your Understanding
- What is the result of
np.array([1, 2, 3]) * 10? - Why does
minutes >= 45produce several Boolean values instead of one? - What does a Boolean mask do?
- Why might you convert a NumPy array back to a list before returning it?
AI Study Aid
Create a chapter diagram
We're looking into to what extent AI-generated diagrams could help with studying.
Use this study aid to generate an AI-generated visual summary of the material you just studied.
Each diagram style emphasizes the content in a different way, so you can choose the focus
that feels most useful.
Using the diagram generator is voluntary and does not affect your course progress. We encourage
you to try it out and see if it helps, but it's totally up to you! Your answers help us understand
how to make better study aids in the future.