NumPy Array Indexing and Slicing Techinques
In NumPy, getting to specific elements and slicing out parts of arrays are key skills for working with data. These actions let you pull out just what you need from an array, making it easier to work with your information. Let’s learn about the ways to access elements and slicing arrays in Numpy.
Accessing Elements
To grab a single item from an array, you use its position, called its index. Each item in an array has its index, starting from 0 for the first item, 1 for the second, and so on. You can get an item by putting its index in square brackets []
after the array’s name.
Example:
import numpy as np my_array = np.array([10, 20, 30, 40, 50]) # Accessing the first element first_element = my_array[0] print("First Element:", first_element) # Accessing the third element third_element = my_array[2] print("Third Element:", third_element)
Output :
First Element: 10
Third Element: 30
Negative Indexing to Access Elements
You can also use negative indexing to grab elements. It is handy when you need to access elements from the end of an array without knowing its length beforehand. For example, -1
refers to the last element, -2
refers to the second-to-last element, and so on.
Example:
import numpy as np my_array = np.array([10, 20, 30, 40, 50]) # Accessing the last element using negative indexing last_element = my_array[-1] print("Last Element:", last_element) # Accessing the second-to-last element second_to_last = my_array[-2] print("Second-to-Last Element:", second_to_last)
Output :
Last Element: 50
Second-to-Last Element: 40
Accessing Individual Element in Multi-dimensional Array
In multidimensional arrays, like grids or tables, you use indices for each dimension separated by commas. For instance, in a 2D array, you specify the row index first, then the column index to get a specific element.
Example:
import numpy as np my_2d_array = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) # Accessing the element in the first row, second column element = my_2d_array[0, 1] print("Element at (0, 1):", element)
Output :
Element at (0, 1): 2
Similarly, for arrays with more dimensions, you provide indices for each dimension accordingly.
Example :
import numpy as np # Creating arrays arr1 = np.array([1, 2, 3, 4, 5, 7, 8, 9]) arr2 = np.array([[1,2,3],[4,5,6]]) arr3 = np.array([[[1,2,3],[4,5,6]],[[7,8,9],[10,11,12]]]) arr4 = np.array([[[[1,2,3],[4,5,6]],[[7,8,9],[10,11,12]]],[[[13,14,15],[16,17,18]],[[19,20,21],[22,23,24]]]]) # Accessing elements print(arr1[1]) # Prints the second element of arr1: 2 print(arr2[1,1]) # Prints the element in the second row and second column of arr2: 5 print(arr3[1,1,2]) # Prints the element in the second block, second row, and third column of arr3: 12 print(arr4[1,0,1,2]) # Prints the element in the second block, first row, second column, and third depth of arr4: 18
Output :
2
5
12
18
Slicing NumPy Arrays
Slicing means taking out a piece, or slice, of an array. This lets you grab a range of items from the array all at once. The slicing syntax in NumPy follows a pattern of start:stop:step
within square brackets []
. Each part of the syntax is optional, and if omitted, defaults to certain values.
Here’s what each part does:
start
: The index where the slice starts (inclusive). If not specified, slicing starts from the beginning.stop
: The index where the slice ends (exclusive). If not specified, slicing goes to the end.step
: The size of the step between elements. If not specified, the step defaults to 1.
Example:
import numpy as np my_array = np.array([10, 20, 30, 40, 50]) # Slicing from index 1 to 3 (exclusive) with a step of 1 slice_result = my_array[1:3] print("Slice Result:", slice_result)
Output :
Slice Result: [20 30]
Slicing Along Multiple Dimensions
In multi-dimensional arrays, you can slice along each dimension separately by specifying multiple slices separated by commas. Each slice corresponds to a different dimension of the array.
For instance, in a 2D array, you provide two slices to specify the range of rows and columns you want to slice:
Example:
import numpy as np my_2d_array = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) # Slicing rows from the first to the second (exclusive) and all columns row_slice = my_2d_array[0:2, :] print("Row Slice:") print(row_slice) # Slicing all rows and columns from the second to the third (exclusive) column_slice = my_2d_array[:, 1:3] print("Column Slice:") print(column_slice)
Output :
Row Slice:
[[1 2 3]
[4 5 6]]
Column Slice:
[[2 3]
[5 6]
[8 9]]
Similarly, for arrays with even more dimensions, you provide slices for each dimension.
Example :
import numpy as np # Creating arrays arr1 = np.array([1, 2, 3, 4, 5, 7, 8, 9]) arr2 = np.array([[1,2,3],[4,5,6]]) arr3 = np.array([[[1,2,3],[4,5,6]],[[7,8,9],[10,11,12]]]) arr4 = np.array([[[[1,2,3],[4,5,6]],[[7,8,9],[10,11,12]]],[[[13,14,15],[16,17,18]],[[19,20,21],[22,23,24]]]]) # Slicing array elements print("First Slice = ",arr1[1:5]) # Prints elements from index 1 to index 4 (exclusive) print("Second Slice = ",arr1[0:8:2]) # Prints elements from index 0 to index 7 (exclusive) with a step size of 2 print("----------------") print("First Slice = ",arr2[1,0:2]) # Prints elements from the second row and the first two columns print("Second Slice = ",arr2[0:2,2]) # Prints elements from the first two rows and the third column print("----------------") print("First Slice = ",arr3[1,0,0:2]) # Prints elements from the first block, first row, and first two columns print("Second Slice = ",arr3[0:2,0,0:2]) # Prints elements from the first two blocks, first row, and first two columns print("----------------") print("First Slice = ",arr4[1,0,1,0:2]) # Prints elements from the second block, first row, second column, and the first two elements print("Second Slice = ",arr4[1,0,0:2,0:2]) # Prints elements from the second block, first row, and the first two rows and columns print("Third Slice = ",arr4[1,0:2,0:2,0:2]) # Prints elements from the second block, first two rows, and first two columns print("Fourth Slice = ",arr4[0:2,0:2,0:2,0:2]) # Prints elements from the first two blocks, first two rows, and first two columns
Output :
First Slice = [2 3 4 5]
Second Slice = [1 3 5 8]
----------------
First Slice = [4 5]
Second Slice = [3 6]
----------------
First Slice = [7 8]
Second Slice = [[1 2]
[7 8]]
----------------
First Slice = [16 17]
Second Slice = [[13 14]
[16 17]]
Third Slice = [[[13 14]
[16 17]]
[[19 20]
[22 23]]]
Fourth Slice = [[[[ 1 2]
[ 4 5]]
[[ 7 8]
[10 11]]]
[[[13 14]
[16 17]]
[[19 20]
[22 23]]]]
Slices are Views, Not Copies
In NumPy, when you slice an array, you’re not making a separate copy. Instead, you’re creating a view into the original array’s data. This means changes you make to the slice also affect the original array, and vice versa.
Example :
import numpy as np original_array = np.array([10, 20, 30, 40, 50]) # Creating a slice slice_view = original_array[1:4] # Modifying an element in the slice slice_view[0] = 99 print("Original Array:", original_array)
Output :
Original Array: [10 99 30 40 50]
Copying vs. Viewing
Copying an array gives you a completely separate copy of its data. Changes to the copy won’t affect the original array, and vice versa.
Viewing an array, on the other hand, gives you a different perspective on the original array’s data. It shares the same data, so changes made to the view also affect the original array.
NumPy provides copy()
and view()
functions to make copies or views explicitly.
You can also check whether the array is copy or view, by using the base
attribute. If the array is a copy, then it will return None
and if it is a view, then it returns the original array.
Example – 1 :
import numpy as np arr=np.array([23,4,3,54,65,87,4,55]) copy_arr=arr.copy() arr[2] = 100 arr[5] = 200 print(arr) print(copy_arr) print(copy_arr.base)
Output :
[ 23 4 100 54 65 200 4 55]
[23 4 3 54 65 87 4 55]
None
Example – 2 :
import numpy as np arr=np.array([23,4,3,54,65,87,4,55]) view_arr=arr.view() arr[2] = 100 arr[5] = 200 arr[6] = 300 print(arr) print(view_arr) print(view_arr.base)
Output :
[ 23 4 100 54 65 200 300 55]
[ 23 4 100 54 65 200 300 55]
[ 23 4 100 54 65 200 300 55]
Advanced Techniques for Accessing Elements
We can also use some advanced techniques for accessing specific elements or subsets of elements in arrays. Let’s explore these techniques:
Indexing with Arrays of Indices
Indexing with arrays of indices involves using another array, known as the index array, to specify which elements to access from the original array. This technique allows for non-contiguous or arbitrary element selection.
Example:
import numpy as np my_array = np.array([10, 20, 30, 40, 50]) # Creating an index array indices = np.array([1, 3, 4]) # Fancy indexing to access specific elements selected_elements = my_array[indices] print("Selected Elements:", selected_elements)
Output :
Selected Elements: [20 40 50]
Boolean Indexing with Boolean Arrays
Boolean indexing is like picking elements based on whether they meet a condition or not. You create a boolean array where True
indicates elements you want, and False
indicates elements you don’t want.
Example:
import numpy as np my_array = np.array([10, 20, 30, 40, 50]) # Creating a boolean mask based on a condition (e.g., greater than 30) mask = my_array > 30 # Using the mask for selection selected_elements = my_array[mask] print("Selected Elements:", selected_elements)
Output:
Selected Elements: [40 50]
Combining Techniques
You can even combine these techniques for more advanced operations. For example, you can use boolean indexing to filter rows based on a condition and then use an array of indices to extract specific columns.
Example:
import numpy as np my_2d_array = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) # Creating a boolean mask for rows where the sum is greater than 10 row_mask = np.sum(my_2d_array, axis=1) > 10 # Creating an index array to select specific columns col_indices = np.array([0, 2]) # Combining boolean and fancy indexing to select rows and specific columns result = my_2d_array[row_mask][:, col_indices] print("Result:") print(result)
Output:
Result:
[[4 6]
[7 9]]