NumPy
Complete Student Notes
Arrays · Indexing · Operations · Statistics · Reshaping · Aggregation
■ Beginner Friendly ■ Data Science Foundation ■ Python / NumPy
Chapter 1: Arrays
The backbone of NumPy – n-dimensional containers for data
What is a NumPy Array?
A NumPy array (ndarray) is a grid of values, all of the same data type. Think of it as a super-powered
Python list that supports math, slicing, and statistics out of the box — much faster than plain lists!
Creating Arrays
Import NumPy first, then create arrays in several ways:
import numpy as np
# 1D array (like a row of numbers)
a = [Link]([10, 20, 30, 40, 50])
# 2D array (rows and columns — like a table)
b = [Link]([[1, 2, 3],
[4, 5, 6]])
# Quick creation helpers
zeros = [Link]((3, 4)) # 3 rows, 4 cols — all 0s
ones = [Link]((2, 3)) # 2 rows, 3 cols — all 1s
rng = [Link](0, 10, 2) # [0, 2, 4, 6, 8]
lin = [Link](0, 1, 5) # 5 evenly spaced values 01
rand = [Link](1, 100, size=(3,3)) # random integers
Key Array Attributes
Attribute What it tells you
[Link] Dimensions — e.g. (3, 4) means 3 rows, 4 cols
[Link] Number of dimensions (1D, 2D, 3D …)
[Link] Total number of elements
[Link] Data type of elements (int64, float64 …)
■ Tip: Always check .shape first when debugging unexpected results.
Chapter 2: Indexing & Slicing
Accessing specific elements, rows, columns, or sub-arrays
Indexing starts at 0 in NumPy. Negative indices count from the end. Slicing uses start:stop:step (stop is
excluded).
1D Indexing
a = [Link]([10, 20, 30, 40, 50])
a[0] # 10 (first element)
a[-1] # 50 (last element)
a[1:4] # [20, 30, 40] (index 1 up to, not including, 4)
a[::2] # [10, 30, 50] (every 2nd element)
a[::-1] # [50, 40, 30, 20, 10] (reversed)
2D Indexing
b = [Link]([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
b[0, 0] # 1 (row 0, col 0)
b[1, 2] # 6 (row 1, col 2)
b[0, :] # [1, 2, 3] (entire row 0)
b[:, 1] # [2, 5, 8] (entire column 1)
b[0:2, 1:3] # [[2,3],[5,6]] (sub-matrix)
Boolean (Fancy) Indexing
Filter elements using conditions — extremely useful in data analysis:
scores = [Link]([45, 78, 92, 55, 88, 61])
# Which scores are above 60?
mask = scores > 60 # [False, True, True, False, True, True]
scores[mask] # [78, 92, 88, 61]
# In one line:
scores[scores > 60] # [78, 92, 88, 61]
scores[(scores >= 55) & (scores <= 80)] # [78, 55, 61]
■■ Remember: Boolean indexing returns a copy, not a view.
Chapter 3: Array Operations
Arithmetic, broadcasting, and element-wise functions
Arithmetic Operations
NumPy operations are element-wise by default — no loops needed! Operations between an array and a
scalar apply to every element.
a = [Link]([1, 2, 3, 4])
b = [Link]([10, 20, 30, 40])
a + b # [11, 22, 33, 44]
b - a # [9, 18, 27, 36]
a * b # [10, 40, 90, 160]
b / a # [10.0, 10.0, 10.0, 10.0]
a ** 2 # [1, 4, 9, 16] (element-wise square)
# Scalar operations (broadcasts to all elements)
a * 5 # [5, 10, 15, 20]
a + 100 # [101, 102, 103, 104]
Broadcasting
Broadcasting lets NumPy operate on arrays of different shapes. A smaller array is 'stretched' to match the
larger one:
matrix = [Link]([[1, 2, 3],
[4, 5, 6]])
row = [Link]([10, 20, 30]) # shape (3,)
matrix + row # row added to EACH row of matrix
# [[11, 22, 33],
# [14, 25, 36]]
Useful Math Functions
Function Description
[Link](a) Square root of each element
[Link](a) Absolute value
[Link](a) e raised to each element
[Link](a) Natural logarithm
[Link](a,2) Round to 2 decimal places
[Link](a) Sum of all elements
Function Description
[Link](a) Running cumulative sum
[Link](a, b) Dot product of two arrays
Chapter 4: Statistical Functions
Mean, Median, Standard Deviation, and more
NumPy has built-in statistical functions that work on entire arrays in one line. You can also apply them
along specific axes (rows or columns).
Core Statistical Functions
data = [Link]([4, 8, 15, 16, 23, 42])
[Link](data) # 18.0 average
[Link](data) # 15.5 middle value
[Link](data) # 12.33 spread around mean
[Link](data) # 152.0 variance (std squared)
[Link](data) # 4 smallest
[Link](data) # 42 largest
[Link](data) # 108 total
[Link](data, 25) # 9.25 25th percentile (Q1)
[Link](data, 75) # 22.25 75th percentile (Q3)
Working with 2D Arrays (axis parameter)
axis=0 works column-wise (down rows). axis=1 works row-wise (across columns):
m = [Link]([[10, 20, 30],
[40, 50, 60]])
[Link](m) # 35.0 (grand average — all elements)
[Link](m, axis=0) # [25. 35. 45.] (average of each column)
[Link](m, axis=1) # [20. 50.] (average of each row)
[Link](m, axis=0) # [50, 70, 90] (sum each column)
[Link](m, axis=1) # [60, 150] (sum each row)
Understanding Mean, Median & Std Dev
Concept Plain English Meaning
Mean (Average) Add all values ÷ count. Affected by outliers.
Median Middle value when sorted. Resistant to outliers.
Std Deviation How spread out values are from the mean. Small = clustered, Large = spread.
Variance Std Dev squared. Same idea, different scale.
Percentile X% of values fall below this point. Useful for grading.
Chapter 5: Reshaping & Aggregation
Changing array shapes and summarising data
Reshaping Arrays
reshape() changes the shape of an array without changing its data. The total number of elements must
stay the same!
a = [Link](1, 13) # [1, 2, 3, ..., 12] — shape (12,)
# Reshape to 3 rows × 4 columns
b = [Link](3, 4)
# [[ 1, 2, 3, 4],
# [ 5, 6, 7, 8],
# [ 9, 10, 11, 12]]
# Use -1 to let NumPy figure out one dimension
c = [Link](4, -1) # shape (4, 3) NumPy calculates 3
# Flatten back to 1D
flat = [Link]() # [1, 2, 3, ..., 12]
flat = [Link]() # same but returns a view (more memory-efficient)
# Transpose — swap rows and columns
b.T # shape becomes (4, 3)
Aggregation Functions
Aggregation collapses an array (or axis) into a single summary value:
sales = [Link]([[200, 350, 150], # Mon
[300, 200, 400], # Tue
[100, 450, 300]]) # Wed
# Total sales
[Link](sales) # 2450
# Daily total (sum across products — axis=1)
[Link](sales, axis=1) # [700, 900, 850]
# Product total (sum across days — axis=0)
[Link](sales, axis=0) # [600, 1000, 850]
# Best selling day
[Link]([Link](sales, axis=1)) # 1 (Tuesday, index 1)
Stacking & Splitting
a = [Link]([1, 2, 3])
b = [Link]([4, 5, 6])
[Link]([a, b]) # vertical stack [[1,2,3],[4,5,6]]
[Link]([a, b]) # horizontal [1, 2, 3, 4, 5, 6]
[Link]([a, b], axis=0) # same as hstack for 1D
# Split into parts
[Link](a, 3) # [array([1]), array([2]), array([3])]
Chapter 6: Student Score Analysis
Applying NumPy concepts to real exam data
Scenario: 5 students took 4 subjects. Each row = one student. Each column = one subject (Math,
Science, English, History).
import numpy as np
# Rows: [Alice, Bob, Carol, Dave, Eve]
# Cols: [Math, Science, English, History]
scores = [Link]([
[85, 90, 78, 92],
[70, 65, 80, 75],
[95, 88, 91, 97],
[60, 72, 55, 68],
[88, 79, 85, 83]
])
# ■■ Per-student stats (axis=1 across subjects) ■■
student_avg = [Link](scores, axis=1)
# Alice:85.75 Bob:72.5 Carol:92.75 Dave:63.75 Eve:83.75
student_total = [Link](scores, axis=1)
# [345, 290, 371, 255, 335]
# ■■ Per-subject stats (axis=0 across students) ■■
subject_avg = [Link](scores, axis=0)
# Math:79.6 Science:78.8 English:77.8 History:83.0
# ■■ Class-wide stats ■■
print('Class Mean :', [Link](scores)) # 79.8
print('Class Median :', [Link](scores)) # 82.0
print('Class Std Dev:', [Link](scores)) # 11.69
# ■■ Find top student ■■
top_idx = [Link](student_avg) # 2 (Carol)
# ■■ Students who passed all subjects (pass mark = 60) ■■
passed = [Link](scores >= 60, axis=1)
# [True, True, True, True, True] — all passed
# ■■ Grade classification ■■
grades = [Link](student_avg >= 85, 'A',
[Link](student_avg >= 70, 'B', 'C'))
# ['B', 'B', 'A', 'C', 'B']
Chapter 7: Sales Array Calculations
Using NumPy for business data analysis
import numpy as np
# Monthly sales for 3 products over 6 months
# Rows = months (Jan-Jun), Cols = [Product A, B, C]
sales = [Link]([
[1200, 850, 630], # Jan
[1350, 920, 710], # Feb
[1100, 780, 590], # Mar
[1450, 1050, 820], # Apr
[1600, 1100, 900], # May
[1380, 970, 760], # Jun
])
# ■■ Basic aggregations ■■
total_revenue = [Link](sales) # grand total
monthly_revenue = [Link](sales, axis=1) # revenue each month
product_revenue = [Link](sales, axis=0) # revenue each product
# ■■ Month-over-month growth (%) ■■
growth = (sales[1:] - sales[:-1]) / sales[:-1] * 100
# Gives % change for each product each month
# ■■ Best month per product ■■
best_month = [Link](sales, axis=0) # [4, 4, 4] (May=index 4)
# ■■ Market share per month ■■
monthly_total = [Link](sales, axis=1, keepdims=True) # (6,1) for broadcasting
market_share = (sales / monthly_total) * 100
# ■■ Sales above target (target = 1000/product/month) ■■
target = 1000
above_target = sales > target
count_above = [Link](above_target) # total occurrences above target
Practice: Product Sales Performance Analysis
Full hands-on exercise using all concepts
Scenario: You are a junior data analyst at TechStore. You have 4 quarters of sales data for 5 products.
Complete all tasks below using NumPy only.
The Dataset
import numpy as np
# Products: Laptop, Phone, Tablet, Headphones, Smartwatch
# Quarters: Q1, Q2, Q3, Q4
sales = [Link]([
[45000, 52000, 48000, 61000], # Laptop
[32000, 35000, 38000, 42000], # Phone
[18000, 21000, 19500, 25000], # Tablet
[ 8500, 11000, 9200, 13500], # Headphones
[12000, 15500, 14000, 18000], # Smartwatch
])
products = ['Laptop', 'Phone', 'Tablet', 'Headphones', 'Smartwatch']
quarters = ['Q1', 'Q2', 'Q3', 'Q4']
Tasks
Calculate total annual revenue for each product (hint: sum across
1. Task 1 — Basic Stats
axis=1).
2. Task 2 — Quarterly
Find the total company revenue per quarter (hint: sum across axis=0).
Analysis
3. Task 3 — Best
Identify the product with the highest total annual sales (use argmax).
Performer
4. Task 4 — Growth Rate Calculate Q4 vs Q1 growth % for each product: (Q4 - Q1) / Q1 * 100.
5. Task 5 — Statistics Find mean, median, and std deviation of all sales values.
What % of total revenue does each product contribute? (product_total
6. Task 6 — Market Share
/ grand_total * 100)
7. Task 7 — Reshape &
Flatten all sales to 1D, sort descending, and identify the top 5 values.
Rank
8. Task 8 — Conditional Find all (product, quarter) combinations where sales exceeded
Filter 40,000.
Complete Solution
# Task 1 – Annual revenue per product
annual = [Link](sales, axis=1)
# [206000, 147000, 83500, 42200, 59500]
# Task 2 – Revenue per quarter
quarterly = [Link](sales, axis=0)
# [115500, 134500, 128700, 159500]
# Task 3 – Best product
best = products[[Link](annual)] # 'Laptop'
# Task 4 – Growth rate Q1Q4
growth = (sales[:, 3] - sales[:, 0]) / sales[:, 0] * 100
# [35.56%, 31.25%, 38.89%, 58.82%, 50.0%]
# Task 5 – Statistics
print('Mean :', [Link](sales).round(2)) # 26945.0
print('Median:', [Link](sales)) # 19750.0
print('Std :', [Link](sales).round(2)) # 16027.67
# Task 6 – Market share
grand_total = [Link](sales)
share = annual / grand_total * 100
# Laptop: 38.4% Phone: 27.4% Tablet: 15.6% ...
# Task 7 – Top 5 sales values
flat = [Link]()
top5 = [Link](flat)[::-1][:5]
# [61000, 52000, 48000, 45000, 42000]
# Task 8 – Sales > 40,000
rows, cols = [Link](sales > 40000)
for r, c in zip(rows, cols):
print(f'{products[r]} in {quarters[c]}: {sales[r,c]}')
Quick Reference Sheet
All key functions at a glance
Category Function / Syntax What it does
Create [Link]([1,2,3]) From Python list
Create [Link]((r,c)) All zeros
Create [Link]((r,c)) All ones
Create [Link](s,e,step) Range of values
Create [Link](s,e,n) n evenly spaced values
Create [Link](l,h,size=(r,c)) Random integers
Index a[i] Element at index i
Index a[r, c] Row r, col c of 2D array
Index a[1:4] Slice from index 1 to 3
Index a[a > 5] Boolean filter
Ops a + b, a * b Element-wise arithmetic
Ops [Link](a, b) Matrix dot product
Stats [Link](a, axis=0) Mean along axis
Stats [Link](a) Median value
Stats [Link](a) Standard deviation
Stats [Link](a, 75) 75th percentile
Stats [Link](a) Index of maximum value
Shape [Link](r, c) Change shape
Shape [Link]() 1D copy
Shape a.T Transpose
Combine [Link]([a,b]) Stack vertically
Combine [Link]([a,b]) Stack horizontally
Aggregate [Link](a, axis=1) Sum across columns
Utility [Link](cond,x,y) Conditional replacement
Utility [Link](a)[::-1] Sort descending