🔢 NumPy in Python

Complete Guide to Numerical Computing — Arrays, Indexing, Matrix Operations

📦 Array Creation

Basic Array Creation

import numpy as np

arr = np.array([1, 2, 3, 4])
print(arr)

→ array([1, 2, 3, 4])

Converting List to Array

a = [1, 2, 3.5, "hello"]
np.array(a)
# array(['1', '2', '3.5', 'hello'], dtype='<U32')

b = [1, 2, 3.5]
np.array(b)
# array([1. , 2. , 3.5])

Vectors vs Matrices

l = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
np.array(l)
# array([[1, 2, 3],
#        [4, 5, 6],
#        [7, 8, 9]])
💡 Vector = 1D linear array  |  Matrix = Multi-dimensional array

Array Generation Functions

np.arange(1, 11, 2)     # array([1, 3, 5, 7, 9])
np.zeros(6)             # array([0., 0., 0., 0., 0., 0.])
np.zeros((3, 3))        # 3x3 matrix of zeros
np.linspace(1, 5, 8)    # 8 evenly spaced values

Random Generation

np.random.rand(10)       # 0 to 1
np.random.randn(10)      # -1 to 1
np.random.randint(6)     # single int 0-6
np.random.randint(6, 254, 21)  # 21 random ints

📊 Array Attributes & Methods

arr = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])

arr.size      # 9 (total elements)
arr.shape     # (3, 3) — rows, cols
arr.dtype     # int64

Statistical Methods

arr.min()     # 1
arr.max()     # 9
arr.sum()     # 45
arr.mean()    # 5.0
arr.std()     # 2.58
arr.argmax()  # 8 (index of max)
arr.argmin()  # 0 (index of min)

Axis-based Operations

np.sum(arr, axis=0)   # Column-wise: [12, 15, 18]
np.sum(arr, axis=1)   # Row-wise:    [6, 15, 24]

Reshaping

arr = np.arange(1, 31)
arr = arr.reshape(5, 6)  # 5 rows, 6 cols
⚠️ Total elements must match — 30 elements → 5×6 ✓

🔍 Indexing & Slicing

1D Array

arr = np.arange(11, 21)
# array([11, 12, 13, 14, 15, 16, 17, 18, 19, 20])

arr[9]              # 20
arr[1:9:2]          # array([12, 14, 16, 18])

Matrix Indexing

arr = np.arange(1, 31).reshape(6, 5)

arr[4]              # array([21, 22, 23, 24, 25])
arr[1, 4]           # 10
arr[:, 2]           # column 2: [3, 8, 13, 18, 23, 28]
arr[0:2, 1:3]       # submatrix

Boolean Indexing

arr = np.arange(11, 21)
boolIndex = arr % 2 == 0
arr[boolIndex]
# array([12, 14, 16, 18, 20])

➗ Array Operations

Arithmetic

a1 = np.array([1, 2, 3, 4, 5])
a2 = np.array([6, 7, 8, 9, 10])

a1 + a2     # [7, 9, 11, 13, 15]
a1 - a2     # [-5, -5, -5, -5, -5]
a1 * a2     # [6, 14, 24, 36, 50]
a1 / a2     # [0.166, 0.285, 0.375, ...]
a1 ** a2    # [1, 128, 6561, 262144, ...]
a1 // a2    # [0, 0, 0, 0, 0]

Broadcasting

arr = np.array([1, 2, 3, 4, 5])
arr + 10
# array([11, 12, 13, 14, 15])

Deep vs Shallow Copy

arr = np.arange(1, 6)

# Shallow copy
sliced = arr[:]
sliced = sliced * 10    # arr UNCHANGED

# Deep copy (reference)
arr1 = arr
arr1[2] = 345           # arr ALSO changed!
⚠️ In NumPy, assignment creates a reference, not a copy. Use .copy() for true copy!

🔢 Matrix Operations

A = np.array([[1, 2], [3, 4]])
B = np.array([[5, 6], [7, 8]])

A @ B           # Matrix multiplication
# array([[19, 22], [43, 50]])

np.dot(A, B)    # Same result

A.T             # Transpose
# array([[1, 3], [2, 4]])

🚀 Advanced Manipulation

Stacking

a = np.array([[1, 2, 3, 4]])
b = np.array([[5, 6, 7, 8]])

np.vstack((a, b))   # Vertical stack
# array([[1, 2, 3, 4],
#        [5, 6, 7, 8]])

np.hstack((a, b))   # Horizontal stack
# array([[1, 2, 3, 4, 5, 6, 7, 8]])

Splitting

c = np.arange(16).reshape(4, 4)

np.hsplit(c, 2)     # Split into 2 vertically
np.vsplit(c, 4)     # Split into 4 horizontally

Why NumPy?