Skip to content
intermediate Phase 8 · Python Data Processing

NumPy Fundamentals

Use NumPy arrays, vectorized operations, and mathematical functions.

1h 30m
0 problems
Topic Progress 0%

NumPy Arrays

Creating Arrays

import numpy as np

# From Python list
arr = np.array([1, 2, 3, 4, 5])
print(arr)        # [1 2 3 4 5]
print(type(arr))  # <class 'numpy.ndarray'>

# 2D array
arr_2d = np.array([[1, 2, 3], [4, 5, 6]])
print(arr_2d)
# [[1 2 3]
#  [4 5 6]]

# Special arrays
zeros = np.zeros((3, 4))      # 3x4 matrix of zeros
ones = np.ones((2, 3))        # 2x3 matrix of ones
empty = np.empty((2, 2))      # Uninitialized
identity = np.eye(4)          # 4x4 identity matrix
range_arr = np.arange(0, 10, 2)  # [0, 2, 4, 6, 8]
linspace = np.linspace(0, 1, 5)  # [0, 0.25, 0.5, 0.75, 1]

# Random arrays
rand = np.random.rand(3, 3)   # Uniform [0, 1)
randn = np.random.randn(3, 3) # Normal distribution
randint = np.random.randint(0, 10, (3, 3))  # Random integers

Array Properties

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

print(arr.shape)    # (2, 3) - rows x columns
print(arr.ndim)     # 2 - number of dimensions
print(arr.size)     # 6 - total elements
print(arr.dtype)    # int64 - data type
print(arr.itemsize) # 8 - bytes per element
print(arr.nbytes)   # 48 - total bytes

NumPy vs Python Lists

# Performance comparison
import time

# Python list
start = time.time()
list_result = [i * 2 for i in range(1000000)]
list_time = time.time() - start

# NumPy array
start = time.time()
arr = np.arange(1000000)
arr_result = arr * 2
np_time = time.time() - start

print(f'List: {list_time:.4f}s')
print(f'NumPy: {np_time:.4f}s')
# NumPy is typically 10-100x faster

Memory Layout

# Contiguous memory block
arr = np.array([1, 2, 3, 4, 5])
print(arr.data)     # Memory buffer
print(arr.ctypes.data)  # Memory address

# Different dtypes
arr_int32 = np.array([1, 2, 3], dtype=np.int32)
arr_float32 = np.array([1, 2, 3], dtype=np.float32)

print(arr_int32.itemsize)   # 4 bytes
print(arr_float32.itemsize) # 4 bytes

Array Operations

Element-wise Operations

import numpy as np

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

# Arithmetic
print(arr + 2)      # [3 4 5 6 7]
print(arr * 3)      # [3 6 9 12 15]
print(arr ** 2)      # [1 4 9 16 25]
print(arr / 2)      # [0.5 1.0 1.5 2.0 2.5]

# Comparison
print(arr > 3)       # [False False False True True]
print(arr == 3)      # [False False True False False]

# Array with array
arr2 = np.array([10, 20, 30, 40, 50])
print(arr + arr2)    # [11 22 33 44 55]

Broadcasting

import numpy as np

# 2D array + 1D array
arr_2d = np.array([[1, 2, 3], [4, 5, 6]])
arr_1d = np.array([10, 20, 30])

result = arr_2d + arr_1d  # Broadcasts across rows
print(result)
# [[11 22 33]
#  [14 25 36]]

# Scalar operations
arr = np.array([[1, 2], [3, 4]])
result = arr * 2  # Broadcasts scalar
print(result)
# [[2 4]
#  [6 8]]

Aggregation Functions

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

print(np.sum(arr))        # 21 - total sum
print(np.sum(arr, axis=0))  # [5 7 9] - sum along rows
print(np.sum(arr, axis=1))  # [6 15] - sum along columns

print(np.mean(arr))       # 3.5
print(np.std(arr))        # 1.707...
print(np.min(arr))        # 1
print(np.max(arr))        # 6
print(np.argmin(arr))     # 0 - index of min
print(np.argmax(arr))     # 5 - index of max

Array Manipulation

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

# Reshape
reshaped = arr.reshape(3, 2)
print(reshaped)
# [[1 2]
#  [3 4]
#  [5 6]]

flattened = arr.flatten()  # [1 2 3 4 5 6]
raveled = arr.ravel()     # Same but view

# Transpose
transposed = arr.T  # [[1 4] [2 5] [3 6]]

# Concatenation
arr1 = np.array([[1, 2], [3, 4]])
arr2 = np.array([[5, 6], [7, 8]])

vstack = np.vstack((arr1, arr2))  # Vertical stack
hstack = np.hstack((arr1, arr2))  # Horizontal stack

# Splitting
arr = np.array([1, 2, 3, 4, 5, 6])
split = np.split(arr, 3)  # [[1, 2], [3, 4], [5, 6]]

Boolean Indexing

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

# Filter
mask = arr > 5
print(arr[mask])  # [6 7 8 9 10]

# Or directly
print(arr[arr > 5])  # [6 7 8 9 10]

# Multiple conditions
print(arr[(arr > 3) & (arr < 8)])  # [4 5 6 7]

# Where
result = np.where(arr > 5, arr, 0)  # Replace False with 0
print(result)  # [0 0 0 0 0 6 7 8 9 10]