Applying various selection techniques to access and modify data within NumPy arrays is demonstrated. This includes basic indexing, slicing, boolean indexing, and fancy indexing.First, ensure you have NumPy imported. If you're following along in a Jupyter Notebook or Python script, start with this line:import numpy as npPreparing Sample ArraysWe need some arrays to work with. Let's create a simple 1D array and a 2D array.# 1D Array arr1d = np.arange(10) # Creates an array [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] print("1D Array:") print(arr1d) # 2D Array (3 rows, 4 columns) arr2d = np.array([[ 1, 2, 3, 4], [ 5, 6, 7, 8], [ 9, 10, 11, 12]]) print("\n2D Array:") print(arr2d)Basic Indexing and SlicingRecall that indexing accesses single elements, while slicing extracts sub-arrays.Practice 1: Accessing ElementsGet the element at index 3 from arr1d.Get the element in the second row (index 1) and third column (index 2) from arr2d.# 1. Element at index 3 from arr1d element_1d = arr1d[3] print(f"Element at index 3 in arr1d: {element_1d}") # 2. Element at row 1, col 2 from arr2d element_2d = arr2d[1, 2] # Or arr2d[1][2] print(f"Element at row 1, col 2 in arr2d: {element_2d}")Practice 2: Slicing ArraysGet the first 5 elements from arr1d.Get the elements from index 5 onwards from arr1d.Get the first two rows from arr2d.Get the first two columns from arr2d.Extract a 2x2 sub-array from the top-right corner of arr2d (rows 0-1, columns 2-3).# 1. First 5 elements of arr1d slice1 = arr1d[:5] print(f"\nFirst 5 elements of arr1d: {slice1}") # 2. Elements from index 5 onwards in arr1d slice2 = arr1d[5:] print(f"Elements from index 5 onwards in arr1d: {slice2}") # 3. First two rows of arr2d slice3 = arr2d[:2] # Rows 0 and 1 print("\nFirst two rows of arr2d:") print(slice3) # 4. First two columns of arr2d slice4 = arr2d[:, :2] # All rows, columns 0 and 1 print("\nFirst two columns of arr2d:") print(slice4) # 5. Top-right 2x2 sub-array of arr2d slice5 = arr2d[:2, 2:] # Rows 0-1, columns 2-3 print("\nTop-right 2x2 sub-array of arr2d:") print(slice5)Boolean IndexingBoolean indexing allows selection based on conditions.Practice 3: Conditional SelectionSelect all elements from arr1d that are greater than 5.Select all rows from arr2d where the element in the first column (index 0) is greater than 4.# 1. Elements > 5 in arr1d bool_mask_1d = arr1d > 5 selected_1d = arr1d[bool_mask_1d] print(f"\nElements in arr1d greater than 5: {selected_1d}") # You can also do this in one step: arr1d[arr1d > 5] # 2. Rows in arr2d where first element > 4 bool_mask_2d = arr2d[:, 0] > 4 # Condition on the first column selected_rows_2d = arr2d[bool_mask_2d] print("\nRows in arr2d where first element > 4:") print(selected_rows_2d)Fancy IndexingFancy indexing uses arrays of indices to select elements.Practice 4: Selecting with Index ArraysFrom arr1d, select the elements at indices 1, 3, and 7.From arr2d, select the rows at index 0 and 2.From arr2d, select the elements at coordinates (0, 1), (1, 3), and (2, 0).# 1. Select specific indices from arr1d indices_1d = np.array([1, 3, 7]) selected_fancy_1d = arr1d[indices_1d] print(f"\nElements at indices {indices_1d} in arr1d: {selected_fancy_1d}") # 2. Select specific rows from arr2d row_indices = np.array([0, 2]) selected_fancy_rows = arr2d[row_indices] # Selects the entire rows print("\nRows at index 0 and 2 from arr2d:") print(selected_fancy_rows) # 3. Select specific elements using coordinate pairs from arr2d row_coords = np.array([0, 1, 2]) col_coords = np.array([1, 3, 0]) selected_fancy_elements = arr2d[row_coords, col_coords] print(f"\nElements at (0,1), (1,3), (2,0) in arr2d: {selected_fancy_elements}")Modifying Array SubsetsYou can assign new values to selections made using any of these indexing methods. Remember that slices often return views, meaning modifications affect the original array, while fancy indexing usually returns copies.Practice 5: Updating Array ValuesChange the element at index 0 in arr1d to 99.Change the first 3 elements of arr1d to 100.Change all elements in arr1d that are even to 0.In arr2d, change the element at (1, 1) to -5.In arr2d, change the entire last row (index 2) to contain only the value 13.print("\nOriginal arr1d before modification:", arr1d) print("Original arr2d before modification:\n", arr2d) # 1. Modify single element in arr1d arr1d_copy1 = arr1d.copy() # Work on a copy to preserve original for next steps arr1d_copy1[0] = 99 print("\n1. arr1d after setting index 0 to 99:", arr1d_copy1) # 2. Modify slice in arr1d arr1d_copy2 = arr1d.copy() arr1d_copy2[:3] = 100 print("2. arr1d after setting first 3 elements to 100:", arr1d_copy2) # 3. Modify based on condition in arr1d arr1d_copy3 = arr1d.copy() arr1d_copy3[arr1d_copy3 % 2 == 0] = 0 # Use boolean indexing for assignment print("3. arr1d after setting even numbers to 0:", arr1d_copy3) # 4. Modify single element in arr2d arr2d_copy1 = arr2d.copy() arr2d_copy1[1, 1] = -5 print("\n4. arr2d after setting element (1,1) to -5:\n", arr2d_copy1) # 5. Modify entire row in arr2d arr2d_copy2 = arr2d.copy() arr2d_copy2[2] = 13 # Assign a scalar to the entire row slice # Alternatively: arr2d_copy2[2, :] = 13 print("5. arr2d after setting the last row to 13:\n", arr2d_copy2) These exercises cover the primary ways you'll interact with data within NumPy arrays. Being comfortable with these selection and modification techniques is fundamental for preparing data for analysis or model training. Experiment further by combining methods, for instance, selecting specific columns from rows chosen by a boolean condition.