Home »
Python
Numpy Array Indexing in Python
Python Numpy Array Indexing: In this tutorial, we are going to learn about the Python Numpy Array indexing, selection, double bracket notations, conditional selection, broadcasting function, etc.
Submitted by Sapna Deraje Radhakrishna, on December 23, 2019
Indexing and Selection
# importing module
import numpy as np
# array declaration
arr = np.arange(0,11)
# printing array
print(arr)
Output
[ 0 1 2 3 4 5 6 7 8 9 10]
Now, to get the index of an element in a Numpy array, it is very similar to how the index is retrieved from a list, for example (Note: In python, the index starts from 0).
# importing module
import numpy as np
# array declaration
arr = np.arange(0,11)
# printing array
print("arr:", arr)
# printing elements based on index
# returns element from given index
print("arr[8]:", arr[8])
# returns the elements between start, end
print("arr[1:5]:", arr[1:5])
# returns the elements between start, end
print("arr[0:5]:", arr[0:5])
#returns the elements until end
print("arr[:6]:", arr[:6])
# returns the elements from start
print("arr[2:]:", arr[2:])
Output
arr: [ 0 1 2 3 4 5 6 7 8 9 10]
arr[8]: 8
arr[1:5]: [1 2 3 4]
arr[0:5]: [0 1 2 3 4]
arr[:6]: [0 1 2 3 4 5]
arr[2:]: [ 2 3 4 5 6 7 8 9 10]
Indexing a 2-D array
Consider the following example,
# importing module
import numpy as np
# 2-D array
arr_2d = np.array([[10,15,20],[25,30,35],[40,45,50]])
# printing array
print(arr_2d)
Output
[[10 15 20]
[25 30 35]
[40 45 50]]
There are two ways to access the index in a 2-D array – Double bracket and single bracket notation. However, the most preferred way is using Single bracket notation. Below are the examples of using double and single bracket notation.
1) Double bracket notation
# importing module
import numpy as np
# 2-D array
arr_2d = np.array([[10,15,20],[25,30,35],[40,45,50]])
# returns 2nd row 1st column
print(arr_2d[1][0])
# returns 1st row 3rd column
print(arr_2d[0][2])
Output
25
20
2) Single bracket condition
# importing module
import numpy as np
# 2-D array
arr_2d = np.array([[10,15,20],[25,30,35],[40,45,50]])
# using slice notation return required values
print(arr_2d[:2,1:])
# returns 1st row 3rd column
print(arr_2d[0,2])
Output
[[15 20]
[30 35]]
20
Conditional selection
Suppose we have a NumPy array,
import numpy as np
arr = np.arange(1,11)
print(arr)
# output: [ 1 2 3 4 5 6 7 8 9 10]
Apply > operator on above created array
bool_arr = arr>4
Comparison Operator will be applied to each element in the array and the number of elements in returned bool Numpy Array will be the same as the original Numpy Array. But for every element that satisfies the condition, there will be True in an array and False for Others in the returned array. The contents of the array will be,
import numpy as np
arr = np.arange(1,11)
bool_arr = arr>4
print(bool_arr)
print(arr)
Output
[False False False False True True True True True True]
[ 1 2 3 4 5 6 7 8 9 10]
Now, to get the conditional results, pass the bool_arr to an arr object and only those elements are returned whose value is true,
print(arr[bool_arr])
# Output: [ 5 6 7 8 9 10]
Implementing the above in a single step,
import numpy as np
arr = np.arange(1,11)
print("arr...")
print(arr)
new_arr = arr[arr>6]
print("new_arr...")
print(new_arr)
Output
arr...
[ 1 2 3 4 5 6 7 8 9 10]
new_arr...
[ 7 8 9 10]
Broadcasting functions
Broadcasting is the method that NumPy uses to allow arithmetic between arrays with different shapes and sizes. Broadcasting solves the problem of arithmetic between arrays of differing shapes by in effect replicating the smaller array along with the mismatched dimension.
NumPy does not duplicate the smaller array; instead, it makes a memory and computationally efficient use of existing structures in memory that in effect achieve the same result.
Example of broadcasting
import numpy as np
arr = np.arange(1,11)
# printing array before broadcasting
print("arr before broadcasting...")
print(arr)
arr[0:5] = 123
# printing array before broadcasting
print("arr before broadcasting...")
print(arr)
Output
arr before broadcasting...
[ 1 2 3 4 5 6 7 8 9 10]
arr before broadcasting...
[123 123 123 123 123 6 7 8 9 10]
An important behavior of broadcasting is explained in the below example,
import numpy as np
arr = np.arange(0,11)
# slice the array
sliced_arr = arr[0:5]
print(sliced_arr)
# broadcast the indicated number to 99
sliced_arr[:] = 99
print(sliced_arr)
# broadcasting also changes the parent array
print(arr)
Output
[0 1 2 3 4]
[99 99 99 99 99]
[99 99 99 99 99 5 6 7 8 9 10]
The reason NumPy does the above is to avoid the memory issue while handling large arrays. In order to retain the original values, there is an option to copy the array explained in below example,
import numpy as np
arr = np.arange(0,11)
print(arr)
arr_copy = arr.copy()
print(arr_copy)
arr_copy[:] = 1
print(arr_copy)
# the parent array is not modified
print(arr)
Output
[ 0 1 2 3 4 5 6 7 8 9 10]
[ 0 1 2 3 4 5 6 7 8 9 10]
[1 1 1 1 1 1 1 1 1 1 1]
[ 0 1 2 3 4 5 6 7 8 9 10]
General broadcasting rules
When operating on two arrays, NumPy compares their shapes element-wise. It starts with the trailing dimensions and works its way forward. Two dimensions are compatible when,
- they are equal, or
- one of them is 1
If these conditions are not met, a ValueError: operands could not be broadcast together exception is thrown, indicating that the arrays have incompatible shapes. The size of the resulting array is the maximum size along each dimension of the input arrays.