ch8s1_WhatIsNumPy
**NumPy** (short for *Numerical Python*) is the core library for **numerical and scientific computing** in Python.
Chapter 8: Introduction to NumPy
Sub-Chapter: What is NumPy? — The Foundation of Numerical Computing
NumPy (short for Numerical Python) is the core library for numerical and scientific computing in Python.
It provides fast, memory-efficient multi-dimensional arrays (ndarray) and a rich set of mathematical, statistical, and linear algebra functions.
NumPy powers almost every data and scientific library in Python — including Pandas, Matplotlib, SciPy, and scikit-learn.
⚙️ 1. Why NumPy?
Python lists are flexible but slow and inefficient for numerical computation. NumPy arrays are:
- Fast (implemented in optimized C)
- Memory-efficient (homogeneous data types)
- Vectorized (no Python loops needed)
Example — List vs. NumPy Array
import numpy as np
import time
# Using Python list
data_list = list(range(1_000_000))
start = time.time()
sum_list = [x * 2 for x in data_list]
print("List time:", time.time() - start)
# Using NumPy array
data_array = np.arange(1_000_000)
start = time.time()
sum_array = data_array * 2
print("NumPy time:", time.time() - start)
🧠 NumPy performs element-wise operations using compiled code — up to 100x faster than Python lists.
🧩 2. Importing NumPy
By convention, NumPy is imported as np:
import numpy as np
🧱 3. Core Concept — The ndarray
An ndarray (n-dimensional array) is NumPy’s main data structure.
It stores homogeneous data in contiguous memory blocks.
arr = np.array([[1, 2, 3], [4, 5, 6]])
print(arr.ndim) # Number of dimensions
print(arr.shape) # Shape (2, 3)
print(arr.dtype) # Data type
| Property | Description | Example |
|---|---|---|
ndim | Number of dimensions | 2 |
shape | Size of each dimension | (2, 3) |
dtype | Data type of elements | int64, float32 |
Visual Representation
[[1, 2, 3],
[4, 5, 6]]
↑
Rows → 2D array (2 × 3)
🧮 4. Creating Arrays
NumPy provides many functions to create arrays efficiently:
a = np.array([1, 2, 3]) # From list
zeros = np.zeros((2, 3)) # All zeros
ones = np.ones((3, 3)) # All ones
range_array = np.arange(0, 10, 2) # Like range()
linspace = np.linspace(0, 1, 5) # 5 equally spaced values
identity = np.eye(3) # Identity matrix
randoms = np.random.rand(2, 2) # Random 2×2 array
🔢 5. Array Operations — Vectorization
NumPy supports vectorized operations, applying mathematical operations directly to arrays.
a = np.array([1, 2, 3])
b = np.array([4, 5, 6])
print(a + b) # [5 7 9]
print(a * b) # [4 10 18]
print(a ** 2) # [1 4 9]
Element-wise Operations
| Operation | Python | NumPy |
|---|---|---|
| Addition | [x + y for x, y in zip(a, b)] | a + b |
| Multiplication | Loop over elements | a * b |
| Power | List comprehension | a ** 2 |
🧠 6. Universal Functions (ufuncs)
NumPy provides optimized vectorized functions that operate on entire arrays.
arr = np.array([0, np.pi/2, np.pi])
print(np.sin(arr)) # [0. 1. 0.]
print(np.log([1, np.e, np.e**2])) # [0. 1. 2.]
print(np.sqrt([1, 4, 9])) # [1. 2. 3.]
Ufuncs eliminate the need for loops and automatically handle broadcasting.
🔁 7. Indexing, Slicing, and Boolean Masking
You can extract elements, slices, or conditions from arrays efficiently.
matrix = np.array([[10, 20, 30], [40, 50, 60], [70, 80, 90]])
print(matrix[0, 1]) # 20
print(matrix[:, 2]) # [30 60 90]
print(matrix[1:, :2]) # [[40 50], [70 80]]
# Boolean masking
mask = matrix > 50
print(matrix[mask]) # [60 70 80 90]
📊 8. Broadcasting — Smart Arithmetic
NumPy allows operations between arrays of different shapes using broadcasting rules.
matrix = np.array([[1, 2, 3], [4, 5, 6]])
vector = np.array([10, 20, 30])
print(matrix + vector)
Output:
[[11 22 33]
[14 25 36]]
Broadcasting Visualization
Matrix (2×3)
[[1, 2, 3],
[4, 5, 6]]
+
Vector (1×3)
[10, 20, 30]
↓
[[11, 22, 33],
[14, 25, 36]]
NumPy automatically expands smaller arrays to match dimensions.
🧮 9. Real-World Example — Normalizing Data
data = np.array([10, 20, 30, 40, 50])
mean = np.mean(data)
std = np.std(data)
normalized = (data - mean) / std
print(normalized)
🧾 10. Common Array Creation Functions
| Function | Description | Example |
|---|---|---|
np.array() | Convert list to array | np.array([1,2,3]) |
np.zeros() | Create array of zeros | np.zeros((3,3)) |
np.ones() | Create array of ones | np.ones((2,2)) |
np.arange() | Range with step | np.arange(0,10,2) |
np.linspace() | Evenly spaced values | np.linspace(0,1,5) |
np.eye() | Identity matrix | np.eye(4) |
np.random.rand() | Random floats | np.random.rand(2,3) |
💡 11. Performance and Memory Efficiency
| Feature | Python Lists | NumPy Arrays |
|---|---|---|
| Type | Heterogeneous | Homogeneous |
| Memory | High overhead | Contiguous, compact |
| Speed | Slower (interpreted) | Fast (C-optimized) |
| Vectorized ops | ❌ | ✅ |
| Broadcasting | ❌ | ✅ |
🧭 12. Summary
| Concept | Description | Example |
|---|---|---|
ndarray | Core array structure | np.array([[1,2],[3,4]]) |
| Vectorization | Fast element-wise computation | a * b |
| Ufuncs | Universal math functions | np.sin(arr) |
| Broadcasting | Automatic dimension expansion | matrix + vector |
NumPy transforms Python into a high-performance mathematical platform. Mastering it unlocks the foundation for data science, AI, and scientific computing.
🧠 Practice Ideas
- Create and manipulate arrays with various shapes.
- Use ufuncs (
np.exp,np.log,np.sqrt) for computation. - Implement normalization and matrix operations.
- Visualize broadcasting behavior with different shapes.