Intermediate
NumPy Indexing, Slicing, and Reshaping
📂 Phase 5: NumPy, Pandas, Data Processing Basics (Days 21–25) · Python ProgrammingWorking with multi-dimensional data — tables, matrices, grids — is where NumPy truly separates itself from plain Python lists. Indexing, slicing, and reshaping arrays correctly is essential before moving into pandas, which is built directly on top of these same underlying concepts.
Indexing a 1D Array
arr = np.array([10, 20, 30, 40, 50])
print(arr[0]) # 10
print(arr[-1]) # 50 — last element
Indexing a 2D Array
matrix = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
print(matrix[0]) # [1 2 3] — entire first row
print(matrix[1, 2]) # 6 — row index 1, column index 2
print(matrix[2][0]) # 7 — alternative syntax, same result
Slicing Arrays
arr = np.array([10, 20, 30, 40, 50])
print(arr[1:4]) # [20 30 40]
print(arr[:3]) # [10 20 30]
print(arr[::2]) # [10 30 50] — every second element
Slicing a 2D Array
matrix = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
print(matrix[0:2, 1:3])
# [[2 3]
# [5 6]]
# rows 0-1, columns 1-2
Views vs Copies — A Critical Distinction
arr = np.array([10, 20, 30, 40, 50])
sliced = arr[1:4] # this is a VIEW, not an independent copy
sliced[0] = 999
print(arr) # [ 10 999 30 40 50] — the ORIGINAL array changed too!
safe_copy = arr[1:4].copy() # an explicit, independent copy
safe_copy[0] = 1
print(arr) # unaffected this time
This is one of the most common sources of subtle bugs for NumPy beginners: unlike slicing a plain Python list (which always copies), slicing a NumPy array returns a VIEW that shares the same underlying memory as the original. Use .copy() explicitly whenever you need an independent slice.
Boolean (Filtering) Indexing
scores = np.array([55, 90, 42, 78, 88])
passing = scores[scores >= 60]
print(passing) # [90 78 88]
# What is actually happening under the hood:
print(scores >= 60) # [False True False True True] — a boolean mask
Reshaping an Array
arr = np.arange(1, 13) # [1 2 3 ... 12], a flat 1D array of 12 elements
reshaped = arr.reshape(3, 4)
print(reshaped)
# [[ 1 2 3 4]
# [ 5 6 7 8]
# [ 9 10 11 12]]
The total number of elements must stay the same before and after reshaping — reshaping 12 elements into (3, 4) works because 3 × 4 = 12; attempting reshape(3, 5) would raise a ValueError.
Flattening a Multi-Dimensional Array
matrix = np.array([[1, 2, 3], [4, 5, 6]])
flat = matrix.flatten()
print(flat) # [1 2 3 4 5 6]
Transposing a Matrix
matrix = np.array([[1, 2, 3], [4, 5, 6]])
print(matrix.T)
# [[1 4]
# [2 5]
# [3 6]]
# rows and columns are swapped
Interview tip: Be ready to explain why arr[1:4] on a NumPy array behaves differently from list_variable[1:4] on a Python list — the NumPy slice is a view sharing memory with the original array, while the list slice always creates a brand-new, independent list. This distinction is a frequent practical/code-reading interview question.