By Fatskills Exam Guides Team — the exam nerds behind 28,500+ quizzes and 2.1M practice questions across 500+ global exams.
ndarray
Hyper-practical guide for Data Science engineers
NumPy (Numerical Python) is the foundation of Python’s data science stack. If you’ve ever used pandas, scikit-learn, or TensorFlow, you’ve used NumPy under the hood. Its core data structure, the ndarray (n-dimensional array), is 10–100x faster than Python lists for numerical operations because it’s implemented in C and optimized for vectorized math.
Numerical Python
You’re building a fraud detection model for a fintech company. Your dataset has 10M transactions, each with 20 features (amount, timestamp, merchant ID, etc.). Using Python lists, preprocessing would take hours. With NumPy, it takes minutes. If you ignore NumPy, your pipeline will fail in production due to slow performance or memory errors.
np.zeros((1000, 1000))
dtype
int32
float64
bool
int16
int64
shape
(3, 4)
arr.shape
axis
axis=0
axis=1
np.sum()
np.mean()
arr[start:stop:step]
.copy()
ufunc
np.add()
np.sin()
ufuncs
math
pip install numpy
You’re working with stock price data (Open, High, Low, Close, Volume). Your goal: 1. Load the data into a NumPy array.2. Extract the last 5 days of closing prices.3. Compute daily returns (percentage change).4. Normalize the data using broadcasting.
import numpy as np # Simulate 10 days of stock data (Open, High, Low, Close, Volume) data = np.array([ [100, 102, 99, 101, 1000000], # Day 1 [101, 103, 100, 102, 1200000], # Day 2 [102, 104, 101, 103, 1100000], # Day 3 [103, 105, 102, 104, 1300000], # Day 4 [104, 106, 103, 105, 1400000], # Day 5 [105, 107, 104, 106, 1500000], # Day 6 [106, 108, 105, 107, 1600000], # Day 7 [107, 109, 106, 108, 1700000], # Day 8 [108, 110, 107, 109, 1800000], # Day 9 [109, 111, 108, 110, 1900000], # Day 10 ]) print("Shape:", data.shape) # (10, 5)
# Extract the "Close" column (4th column, index 3) close_prices = data[:, 3] # All rows, column 3 print("Closing prices:", close_prices) # Output: [101 102 103 104 105 106 107 108 109 110] # Get last 5 days of closing prices last_5_days = close_prices[-5:] # Slice from 5th last to end print("Last 5 days:", last_5_days) # Output: [106 107 108 109 110]
# Daily returns = (Today's Close - Yesterday's Close) / Yesterday's Close daily_returns = (close_prices[1:] - close_prices[:-1]) / close_prices[:-1] print("Daily returns:", daily_returns) # Output: [0.0099 0.0098 0.0097 0.0096 0.0095 0.0094 0.0093 0.0092 0.0091]
# Subtract mean and divide by std (standardization) mean = np.mean(data, axis=0) # Mean of each column std = np.std(data, axis=0) # Std of each column normalized_data = (data - mean) / std # Broadcasting! print("Normalized data (first row):", normalized_data[0]) # Output: [-1.486 -1.486 -1.486 -1.486 -1.486] (approx)
# Check shapes print("Original shape:", data.shape) # (10, 5) print("Normalized shape:", normalized_data.shape) # (10, 5) # Check mean of normalized data (should be ~0) print("Mean of normalized data:", np.mean(normalized_data, axis=0)) # Output: [~0, ~0, ~0, ~0, ~0]
dtype=np.float32
del arr
np.save()
np.load()
.npy
.csv
print(arr.shape)
np.allclose()
==
python np.seterr(all='warn') # Warn on invalid operations
.values
.to_numpy()
ValueError: operands could not be broadcast together
arr1.shape
arr2.shape
np.where()
"Given arr = np.array([1, 2, 3, 4, 5]), what does arr[1:4] return?" Answer: [2, 3, 4] (stop index is exclusive).
arr = np.array([1, 2, 3, 4, 5])
arr[1:4]
[2, 3, 4]
Broadcasting:
"Can you add a (3,) array to a (3, 3) array?" Answer: Yes—NumPy broadcasts the (3,) array to (3, 3).
(3,)
(3, 3)
Performance:
"Why is np.sum(arr) faster than sum(arr)?" Answer: np.sum() is vectorized (C-optimized), while sum() is a Python loop.
np.sum(arr)
sum(arr)
sum()
Memory:
arr.astype(np.float32)
(4,)
Given:
arr = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
Task: Extract the anti-diagonal (top-right to bottom-left) using slicing.Expected Output: [3, 5, 7]
[3, 5, 7]
anti_diagonal = arr[::-1, ::1].diagonal() # Reverse rows, then take diagonal # Or: anti_diagonal = arr[::-1, :].diagonal() # Same as above print(anti_diagonal) # [3 5 7]
Why it works:- arr[::-1, :] reverses the rows ([[7,8,9], [4,5,6], [1,2,3]]).- .diagonal() extracts the main diagonal ([7,5,3]).- But we want [3,5,7], so we reverse the result: arr[::-1, ::1].diagonal().
arr[::-1, :]
[[7,8,9], [4,5,6], [1,2,3]]
.diagonal()
[7,5,3]
[3,5,7]
arr[::-1, ::1].diagonal()
np.array([1, 2, 3])
np.zeros((3, 3))
np.arange(0, 10, 2)
range()
np.linspace(0, 1, 5)
np.random.rand(3, 3)
(rows, cols)
arr.reshape(3, 2)
arr[1:4, 2:5]
start:stop:step
arr + 5
np.sqrt(arr)
np.sum(arr, axis=0)
np.save('arr.npy', arr)
arr2 = arr[1:3]
arr
np.array([1, 2.5])
float
Join 4M+ learners. Unlock unlimited quizzes, wrong-answer tracking, flashcards + reminders, study guides, and 1-on-1 challenges.