NumPy is the first real data library you encounter in Class 11 AI — and it is the foundation that everything else (Pandas, Scikit-learn, Matplotlib) is built on. If NumPy feels confusing right now, this tutorial will fix that. Every concept explained, every program you need for your practical file, ready to run.
This tutorial covers Unit 3: Python Programming (Level 2) and Unit 5: Data Literacy of the CBSE AI Class 11 syllabus (Subject Code 843, 2025-26).
What You’ll Learn
- What NumPy is and why it exists (the short, honest answer)
- How to create and work with 1D and 2D NumPy arrays
- All statistical operations your practical file and Viva will test
- Matrix operations as required in Unit 5
- 8 complete programs — copy-ready for your practical file
What Is NumPy and Why Do You Need It?
NumPy stands for Numerical Python. It is a library — a collection of pre-written code — that makes working with large sets of numbers fast and simple.
Here is the honest reason it exists: Python lists are flexible but slow for mathematics. Adding two lists in plain Python requires a loop. NumPy does the same thing in one line, and 50× faster because it processes data in batches rather than one element at a time.
In AI and data science, you constantly work with hundreds or thousands of numbers — exam marks, sensor readings, pixel values, temperatures. NumPy handles all of it cleanly.
python
# Without NumPy — slow, verbose
a = [10, 20, 30]
b = [5, 10, 15]
result = [a[i] + b[i] for i in range(len(a))]
# With NumPy — fast, one line
import numpy as np
result = np.array(a) + np.array(b)
Both produce [15, 30, 45]. The NumPy version wins at scale.
Installing and Importing NumPy
NumPy comes pre-installed with Anaconda. If you have Anaconda set up (see our Complete Python Programming Guide), you are ready to go.
python
import numpy as np
The as np part is a standard alias — it means you type np.array() instead of numpy.array() every time. Every data scientist in the world uses this alias. Use it in your practical file too.
Part 1 — Creating NumPy Arrays
1D Arrays (One-Dimensional)
A 1D array is like a list but with superpowers.
python
# Program to create and inspect a 1D NumPy array
import numpy as np
# From a Python list
marks = np.array([72, 85, 91, 68, 78, 95, 88])
print("Array :", marks)
print("Type :", type(marks))
print("Data type :", marks.dtype) # int64 — type of elements
print("Shape :", marks.shape) # (7,) — 7 elements, 1 dimension
print("Dimensions :", marks.ndim) # 1
print("Total elements:", marks.size) # 7
Expected Output:
Array : [72 85 91 68 78 95 88]
Type : <class 'numpy.ndarray'>
Data type : int64
Shape : (7,)
Dimensions : 1
Total elements: 7
Key attributes to remember for Viva:
| Attribute | What It Returns | Example |
|---|---|---|
.dtype | Data type of elements | int64, float64 |
.shape | Tuple showing dimensions | (7,) for 1D, (3,3) for 2D |
.ndim | Number of dimensions | 1 or 2 |
.size | Total number of elements | 7 |
2D Arrays (Matrices)
A 2D array is a table — rows and columns. This is what the Unit 5 matrix content refers to.
python
# Program to create and inspect a 2D NumPy array (matrix)
import numpy as np
# 3×3 matrix
matrix = np.array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
print("Matrix:\n", matrix)
print("Shape :", matrix.shape) # (3, 3) — 3 rows, 3 columns
print("Dimensions :", matrix.ndim) # 2
print("Total elements:", matrix.size) # 9
# Accessing elements: [row_index, column_index]
print("Element at row 1, col 2:", matrix[1, 2]) # → 6
print("Entire row 0:", matrix[0]) # → [1 2 3]
print("Entire col 1:", matrix[:, 1]) # → [2 5 8]
Expected Output:
Matrix:
[[1 2 3]
[4 5 6]
[7 8 9]]
Shape : (3, 3)
Dimensions : 2
Total elements: 9
Element at row 1, col 2: 6
Entire row 0: [1 2 3]
Entire col 1: [2 5 8]
Indexing logic:
matrix[1, 2]→ row index 1 (second row), column index 2 (third column) → value 6matrix[0]→ entire first rowmatrix[:, 1]→ the:means “all rows”, column index 1 → entire second column
Special Arrays — zeros, ones, arange, linspace
These are frequently asked in Viva because they appear in real AI workflows.
python
# Program to create special NumPy arrays
import numpy as np
# Array of zeros
z = np.zeros((3, 3))
print("Zeros:\n", z)
# Array of ones
o = np.ones((2, 4))
print("Ones:\n", o)
# Array with a range of values (like Python's range())
r = np.arange(0, 20, 5) # start=0, stop=20, step=5
print("Arange:", r) # [0 5 10 15]
# Array with evenly spaced values
l = np.linspace(0, 1, 5) # 5 values between 0 and 1
print("Linspace:", l) # [0. 0.25 0.5 0.75 1. ]
# Identity matrix
eye = np.eye(3)
print("Identity matrix:\n", eye)
Expected Output:
Zeros:
[[0. 0. 0.]
[0. 0. 0.]
[0. 0. 0.]]
Ones:
[[1. 1. 1. 1.]
[1. 1. 1. 1.]]
Arange: [ 0 5 10 15]
Linspace: [0. 0.25 0.5 0.75 1. ]
Identity matrix:
[[1. 0. 0.]
[0. 1. 0.]
[0. 0. 1.]]
arange vs linspace:
arange(start, stop, step)— you control the step sizelinspace(start, stop, n)— you control the number of points
Part 2 — Array Operations
Element-Wise Arithmetic
python
# Program to demonstrate element-wise arithmetic operations
import numpy as np
a = np.array([10, 20, 30, 40, 50])
b = np.array([2, 4, 6, 8, 10])
print("Addition :", a + b) # [12 24 36 48 60]
print("Subtraction :", a - b) # [ 8 16 24 32 40]
print("Multiplication :", a * b) # [ 20 80 180 320 500]
print("Division :", a / b) # [5. 5. 5. 5. 5.]
print("Exponent :", a ** 2) # [ 100 400 900 1600 2500]
print("Scalar multiply:", a * 3) # [ 30 60 90 120 150]
Expected Output:
Addition : [12 24 36 48 60]
Subtraction : [ 8 16 24 32 40]
Multiplication : [ 20 80 180 320 500]
Division : [5. 5. 5. 5. 5.]
Exponent : [ 100 400 900 1600 2500]
Scalar multiply: [ 30 60 90 120 150]
NumPy applies the operation to every element automatically. No loop needed.
Matrix Operations (Unit 5 — Matrices)
python
# Program to demonstrate matrix operations using NumPy
import numpy as np
A = np.array([[1, 2], [3, 4]])
B = np.array([[5, 6], [7, 8]])
# Matrix addition
print("A + B:\n", A + B)
# Matrix multiplication (dot product)
print("A × B (dot product):\n", np.dot(A, B))
# Transpose
print("Transpose of A:\n", A.T)
# Determinant
det = np.linalg.det(A)
print("Determinant of A:", det)
Expected Output:
A + B:
[[ 6 8]
[10 12]]
A × B (dot product):
[[19 22]
[43 50]]
Transpose of A:
[[1 3]
[2 4]]
Determinant of A: -2.0000000000000004
Why this matters in Unit 5: The CBSE Class 11 syllabus explicitly covers matrices and their operations in Unit 5. NumPy’s np.dot() for multiplication and .T for transpose are the standard Python implementations.
Part 3 — Statistical Operations (Unit 5)
This is the section directly mapped to the CBSE practical requirement: “Python programs to demonstrate the use of mean, median, mode, standard deviation and variance.”
python
# Program to calculate all five statistical measures using NumPy
import numpy as np
from scipy import stats
# Class 11 student marks in AI subject
data = np.array([55, 60, 65, 70, 72, 75, 80, 80, 85, 90, 90, 90, 95])
print("Dataset :", data)
print("Count :", len(data))
print("Mean :", round(np.mean(data), 2))
print("Median :", np.median(data))
print("Mode :", stats.mode(data, keepdims=True).mode[0])
print("Std Deviation:", round(np.std(data), 2))
print("Variance :", round(np.var(data), 2))
print("Minimum :", np.min(data))
print("Maximum :", np.max(data))
print("Range :", np.max(data) - np.min(data))
Expected Output:
Dataset : [55 60 65 70 72 75 80 80 85 90 90 90 95]
Count : 13
Mean : 77.46
Median : 80.0
Mode : 90
Std Deviation: 11.52
Variance : 132.71
Minimum : 55
Maximum : 95
Range : 40
What each measure means — Viva-ready definitions:
| Measure | Definition | NumPy Function |
|---|---|---|
| Mean | Sum of all values ÷ count | np.mean() |
| Median | Middle value when data is sorted | np.median() |
| Mode | Most frequently occurring value | stats.mode() (from scipy) |
| Standard Deviation | Average distance of each value from the mean | np.std() |
| Variance | Square of standard deviation | np.var() |
| Range | Maximum − Minimum | np.max() - np.min() |
Part 4 — Reshaping and Slicing
These operations come up in Scikit-learn programs and are commonly asked in Viva.
python
# Program to demonstrate reshaping and slicing
import numpy as np
# Reshape: change dimensions without changing data
arr = np.array([1, 2, 3, 4, 5, 6])
reshaped = arr.reshape(2, 3) # 2 rows, 3 columns
print("Original :", arr)
print("Reshaped:\n", reshaped)
# reshape(-1, 1) — converts to column vector (needed for Scikit-learn)
col = arr.reshape(-1, 1)
print("Column vector:\n", col)
print("Shape:", col.shape) # (6, 1)
# Slicing
data = np.array([10, 20, 30, 40, 50, 60, 70, 80])
print("\nFirst 4 elements :", data[:4]) # [10 20 30 40]
print("Last 3 elements :", data[-3:]) # [60 70 80]
print("Every 2nd element:", data[::2]) # [10 30 50 70]
print("Reversed :", data[::-1]) # [80 70 60 50 40 30 20 10]
Expected Output:
Original : [1 2 3 4 5 6]
Reshaped:
[[1 2 3]
[4 5 6]]
Column vector:
[[1]
[2]
[3]
[4]
[5]
[6]]
Shape: (6, 1)
First 4 elements : [10 20 30 40]
Last 3 elements : [60 70 80]
Every 2nd element: [10 30 50 70]
Reversed : [80 70 60 50 40 30 20 10]
Why reshape(-1, 1) matters: Scikit-learn’s machine learning functions require feature data in column format — each feature as a column, each sample as a row. When you have one feature (e.g., study hours), you reshape it to (-1, 1) before passing to .fit(). The -1 tells NumPy to calculate the row count automatically.
Part 5 — Boolean Indexing and Filtering
python
# Program to filter array elements using conditions (Boolean indexing)
import numpy as np
marks = np.array([45, 62, 78, 55, 88, 91, 49, 73, 85, 67])
# Find all marks above 70
above_70 = marks[marks > 70]
print("Marks above 70 :", above_70)
# Count students who passed (marks >= 33)
passed = np.sum(marks >= 33)
print("Number who passed :", passed)
# Find positions (indices) where marks exceed 80
positions = np.where(marks > 80)
print("Positions where marks > 80:", positions[0])
print("Values at those positions :", marks[marks > 80])
Expected Output:
Marks above 70 : [78 88 91 73 85 67]
Number who passed : 10
Positions where marks > 80: [4 5 8]
Values at those positions : [88 91 85]
This technique — filtering an array by a condition — is called boolean indexing. It is the same logic used in Pandas (df[df["Marks"] > 70]) and appears throughout data science work.
NumPy vs Python List — When to Use Which
| Situation | Use Python List | Use NumPy Array |
|---|---|---|
| Storing mixed data types | ✅ | ❌ (all elements must be same type) |
| Simple storage, no maths | ✅ | Not necessary |
| Mathematical operations | ❌ (slow, needs loops) | ✅ |
| Working with datasets | ❌ | ✅ |
| Input to Scikit-learn / Pandas | ❌ | ✅ |
| Matrix operations | ❌ | ✅ |
Quick Revision Box
| Function / Attribute | What It Does |
|---|---|
np.array([...]) | Creates a NumPy array from a list |
.shape | Returns dimensions as a tuple |
.dtype | Returns element data type |
.ndim | Returns number of dimensions |
.size | Returns total element count |
np.zeros((r,c)) | Creates array of zeros with r rows, c columns |
np.ones((r,c)) | Creates array of ones |
np.arange(a,b,s) | Values from a to b with step s |
np.linspace(a,b,n) | n evenly spaced values between a and b |
np.eye(n) | n×n identity matrix |
np.dot(A, B) | Matrix multiplication |
A.T | Transpose of matrix A |
np.linalg.det(A) | Determinant of matrix A |
.reshape(r, c) | Reshapes array to r rows, c columns |
.reshape(-1, 1) | Converts to column vector |
np.mean() | Mean (average) |
np.median() | Median (middle value) |
np.std() | Standard deviation |
np.var() | Variance |
np.where(condition) | Returns indices where condition is True |
Practice Questions
Q1 (2 marks): Write a Python program to create a NumPy array [5, 10, 15, 20, 25] and find its mean, standard deviation, and shape.
Model Answer:
python
import numpy as np
arr = np.array([5, 10, 15, 20, 25])
print("Mean :", np.mean(arr))
print("Std Deviation :", np.std(arr))
print("Shape :", arr.shape)
Output: Mean: 15.0 Std Deviation: 7.07 Shape: (5,)
Q2 (MCQ): What does arr.reshape(-1, 1) do when arr has 6 elements?
a) Creates a 1×6 array (1 row, 6 columns) b) Creates a 6×1 array (6 rows, 1 column) c) Flattens the array to 1 dimension d) Reverses the array
Answer: b) Creates a 6×1 array — -1 tells NumPy to calculate the row count automatically, and 1 specifies 1 column. 6 elements ÷ 1 column = 6 rows.
Frequently Asked Questions
Q1: Do I need to import NumPy every time I write a program? Yes — every program file must have import numpy as np at the top. The import only loads the library for that program’s session. In Jupyter Notebook, if you run the import cell first, all subsequent cells in the same session can use np. If you restart the kernel, you need to run the import cell again.
Q2: What is the difference between np.dot(A, B) and A * B for 2D arrays? A * B does element-wise multiplication — each position multiplied with the matching position. np.dot(A, B) does true matrix multiplication (row × column). In mathematics when you say “multiply two matrices,” you mean np.dot(). Use A * B only when you specifically want element-wise multiplication.
Q3: Why does Scikit-learn require reshape(-1, 1) for single features? Scikit-learn expects feature data as a 2D array where rows are samples and columns are features. A plain 1D array like [1, 2, 3, 4] has shape (4,) — Scikit-learn can’t tell if it’s 4 samples with 1 feature or 1 sample with 4 features. Reshaping to (-1, 1) gives shape (4, 1) — unambiguously 4 samples, 1 feature each.