Numpy Array Indexing & Slicing

Jahid Hasan
9 min readJul 21, 2019

--

Already I have three posts about numpy in this medium site. Here is the link,

Already I have three posts about numpy in this medium site. Here is the link,

1) Introduction to Basic Numpy

2) Basic Numpy method for Data Science

3) Python Numpy Foundation

please visit these link for more details. Today I wanna discuss numpy indexing and slicing.

NumPy slices and indexes

The contents of a ndarray object can be accessed and modified by indexing or slicing, just like the slicing of a list in Python.

we have a list here of six elements and we can take for instance everything from the element with number 1 onwards or we can take everything between element number 0.

>>> a = np.array([127,27,96,147,267,2])
>>> a[1:]
array([ 27, 96, 147, 267, 2])
>>> a[0:2]
array([127, 27])
>>> a[::3]
array([127, 147])
>>> b = a[3:5]
>>> b
array([147, 267])
>>> b[1]
267
>>> b[:] = 125
>>> b
array([125, 125])
>>> a
array([127, 27, 96, 125, 125, 2])
'''
Now if you look at our previous 'a' which was a= ([ 27, 96, 147, 267, 2]) But now checking the values of a, we see that the values of a has been replaced by the values of b. That is the big problem. That is important to remember when you're creating a slice of an array you're not creating a new array you're actually just working with that same old array you just create a view of that array. So why does that happen well that's just a way that Python or numpy protects the memory of the computer so if you create copies and copies of arrays then unnecessarily then that will just take up memory space.So, python automatically or numpy automatically protects that us.
'''
>>> c = a.copy()
>>> c
array([127, 27, 96, 125, 125, 2])
>>> c[1] = 69
>>> c
array([127, 69, 96, 125, 125, 2])
>>> a
array([127, 27, 96, 125, 125, 2])

ndarray arrays can be indexed based on 0 — n subscripts. Slice objects can be cut from the original array by using the built-in slice function and setting the start, stop and step parameters.

>>> import numpy as np
>>> a = np.arange(12)
>>> s = slice(2,9,2)
>>> print (a[s])
[2 4 6 8]

In the above example, we first create an ndarray object with the arange() function. Then, set the start, end, and step parameters to 2, 9, and 2, respectively.

We can also slice the slice parameter start : stop: step by a colon :

>>> a = np.arange(12) 
>>> b = a[2:9:2]
>>> print(b)
[2 4 6 8]

Explanation of colon: If only one parameter, such as [2] is placed a single element corresponding to the index will be returned. If it is [2:], it means that all items from the beginning of the index will be extracted. If two parameters are used, such as [2:7], then the item between the two indexes (excluding the stop index) is extracted.

>>> a = np.arange(10) 
>>> b = a[5]
>>> print(b)
5

Slicing operation

The slicing operation of multidimensional data in Numpy is the same as the slicing operation for lists in Python. The parameters consist of three parts: start, stop and step.

>>> arr = np.arange(12)
>>> print ('array is:', arr)
array is: [ 0 1 2 3 4 5 6 7 8 9 10 11]
>>> slice_one = arr[:5]
>>> print ('slice begins at 0 and ends at 5:', slice_one)
slice begins at 0 and ends at 5: [0 1 2 3 4]

>>> slice_two = arr[6:9]
>>> print ('slice begins at 6 and ends at 9:', slice_two)
slice begins at 6 and ends at 9: [6 7 8]

>>> slice_three = arr[0:12:3]
>> print ('slice begins at 0 and ends at 12 with step 3:', slice_three)
slice begins at 0 and ends at 12 with step 3: [0 3 6 9]

Numpy above is an example of the operation of one-dimensional data, if a multi-dimensional array, each dimension between just use a comma-separated.

Note: Slices are all closed before opening, ie the result of the slice includes start, but does not include a stop

>>> arr = np.arange(16).reshape((4, 4))
>>> arr
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11],
[12, 13, 14, 15]])
>>> slice_two = arr[:, ::2]
>>> slice_two
array([[ 0, 2],
[ 4, 6],
[ 8, 10],
[12, 14]])

For multidimensional arrays with dimensions greater than 3, you can also simplify the operation with ‘…’

>>> arr = np.arange(24).reshape((2, 4, 3))
>>> arr
array([[[ 0, 1, 2],
[ 3, 4, 5],
[ 6, 7, 8],
[ 9, 10, 11]],

[[12, 13, 14],
[15, 16, 17],
[18, 19, 20],
[21, 22, 23]]])
>>> c = arr[0, ...] #Equivalent to arr[0, :, :]
>>> c
array([[ 0, 1, 2],
[ 3, 4, 5],
[ 6, 7, 8],
[ 9, 10, 11]])
>>> d = d = arr[..., 2] #Equivalent to arr[:, :, 2]
>>> d
array([[ 2, 5, 8, 11],
[14, 17, 20, 23]])

Indexing operation

For multidimensional arrays, the most common operation is to get the value of a specific location, as shown below:

>>> arr = np.array([
[1, 2, 3, 4],
[2, 4, 6, 8],
[3, 6, 9, 12],
[4, 8, 12, 16],
[5, 10, 15, 24]])
>>> arr[2, 2] # The value of the third column and the third row
9

In contrast, Python gets the same location for the list as follows:

>>> a = arr[2][2]
>>> a
9

In contrast, a two-dimensional array may not be the same for the same operation. Imagine if it is a 10-dimensional array, then it takes 10 pairs [] to perform the standard operation of the Python index list, and only one pair is required to perform the numpy operation.

Get multiple elements

In fact, in Numpy’s indexing operation ‘x = arr[obj]’, obj is more than just a sequence of numbers separated by commas, but also more complex.

1. A sequence of arrays separated by commas

  • The length of the array sequence must be the same as the dimension of the multidimensional array
  • The length of each array in the sequence must be the same
>>> a = arr[[1, 3], [3, 1]]
>>> a
array([8, 8])

For the above example, first select row 1 and row 3, then row 4 of row 1 and column 2 of row 3 to form a new array.

2.boolean/mask index

The so-called boolean index is to use a form of boolean expression to determine the index, such as the following example

>>> arr
array([[ 1, 2, 3, 4],
[ 2, 4, 6, 8],
[ 3, 6, 9, 12],
[ 4, 8, 12, 16],
[ 5, 10, 15, 24]])
>>> booli = arr > 4
>>> booli
array([[False, False, False, False],
[False, False, True, True],
[False, True, True, True],
[False, True, True, True],
[ True, True, True, True]])
>>> a = arr[booli]
>>> a
array([ 6, 8, 6, 9, 12, 8, 12, 16, 5, 10, 15, 24])

Similarities and differences between slices and indexes

Slices and indexes are methods for getting the elements in an array, but there are differences between the two:

  1. The slice gets a view of the original multidimensional array. Modifying the contents of the slice will also cause the value of the original array to change.
  2. Slices are continuous or consecutively arranged in a certain step size, while the index yields values ​​at arbitrary positions with greater degrees of freedom.

NumPy Advanced Index

NumPy provides more indexing than normal Python sequences. In addition to the previously used indexes for integers and slices, arrays can be indexed by integer arrays, boolean indexes, and fancy indexes.

Integer array index

The following example gets the elements at the (0,0), (1,1), and (2,0) positions in the array.

>>> x = np.array([[10, 11], [12, 13], [14, 15]])
>>> y = x[[0,1,2], [1,0,1]]
array([11, 12, 15])

The schematic diagram of this solution

The following example gets the elements of the four corners in a 4 X 3 array. The row index is [0,0] and [3,3], and the column index is [0,2] and [0,2].

>>> x = np.array([[10, 11, 12],[13, 14, 15],[16, 17, 18],[ 19, 20, 21]])
>>> x
array([[10, 11, 12],
[13, 14, 15],
[16, 17, 18],
[19, 20, 21]])
>>> rows = np.array([[1,1],[3,3]])
>>> rows
array([[1, 1],
[3, 3]])
>>> cols = np.array([[1,2],[2,0]])
>>> cols
array([[1, 2],
[2, 0]])
>>> y = x[rows,cols]
>>> y
array([[14, 15],
[21, 19]])
'''
(1,1) and (1,2) [1 row 1 column = 14; 1 row 2 column = 15]
(3,3) and (2,0) [3 row 2 column = 21; 3 row 0 column = 19]
'''

The result returned is a ndarray object containing each corner element.

The following example uses ~ (the complement operator) to filter NaN.

>>> x= np.array([np.nan, 1, np.nan, 2, np.nan, 3, 4, np.nan,5, np.nan, 6])
>>> y = (x[~np.isnan(x)])
>>> y
array([1., 2., 3., 4., 5., 6.])

The following example demonstrates how to filter out non-complex elements from an array.

>>> x = np.array([2, 3+9j, 8, 7.5+10j])
>>> y = (x[np.iscomplex(x)])
>>> y
array([3. +9.j, 7.5+10.j])

Fancy index

Fancy index refers to indexing with an array of integers.

The fancy index takes the value of the indexed array as the index of an axis of the target array. For a one-dimensional integer array as an index, if the target is a one-dimensional array, the result of the index is the element corresponding to the position; if the target is a two-dimensional array, then the row corresponding to the subscript.

Fancy indexes are not the same as for slices, they always copy data into a new array.

1, the incoming sequence index array

>>> x = np.arange(81).reshape((9,9))
>>> x
array([[ 0, 1, 2, 3, 4, 5, 6, 7, 8],
[ 9, 10, 11, 12, 13, 14, 15, 16, 17],
[18, 19, 20, 21, 22, 23, 24, 25, 26],
[27, 28, 29, 30, 31, 32, 33, 34, 35],
[36, 37, 38, 39, 40, 41, 42, 43, 44],
[45, 46, 47, 48, 49, 50, 51, 52, 53],
[54, 55, 56, 57, 58, 59, 60, 61, 62],
[63, 64, 65, 66, 67, 68, 69, 70, 71],
[72, 73, 74, 75, 76, 77, 78, 79, 80]])
>>> y = (x[[7,0,8,5,2]])
>>> y
array([[63, 64, 65, 66, 67, 68, 69, 70, 71],
[ 0, 1, 2, 3, 4, 5, 6, 7, 8],
[72, 73, 74, 75, 76, 77, 78, 79, 80],
[45, 46, 47, 48, 49, 50, 51, 52, 53],
[18, 19, 20, 21, 22, 23, 24, 25, 26]])

2, passed in the reverse index array

>>> x = np.arange(81).reshape((9,9))
>>> x
array([[ 0, 1, 2, 3, 4, 5, 6, 7, 8],
[ 9, 10, 11, 12, 13, 14, 15, 16, 17],
[18, 19, 20, 21, 22, 23, 24, 25, 26],
[27, 28, 29, 30, 31, 32, 33, 34, 35],
[36, 37, 38, 39, 40, 41, 42, 43, 44],
[45, 46, 47, 48, 49, 50, 51, 52, 53],
[54, 55, 56, 57, 58, 59, 60, 61, 62],
[63, 64, 65, 66, 67, 68, 69, 70, 71],
[72, 73, 74, 75, 76, 77, 78, 79, 80]])
>>> y = (x[[-7,-1,-8,-5,-9]])
>>> y
array([[18, 19, 20, 21, 22, 23, 24, 25, 26],
[72, 73, 74, 75, 76, 77, 78, 79, 80],
[ 9, 10, 11, 12, 13, 14, 15, 16, 17],
[36, 37, 38, 39, 40, 41, 42, 43, 44],
[ 0, 1, 2, 3, 4, 5, 6, 7, 8]])

3, incoming multiple index array (to use np.ix_)

>>> x = np.arange(81).reshape((9,9))
>>> x
array([[ 0, 1, 2, 3, 4, 5, 6, 7, 8],
[ 9, 10, 11, 12, 13, 14, 15, 16, 17],
[18, 19, 20, 21, 22, 23, 24, 25, 26],
[27, 28, 29, 30, 31, 32, 33, 34, 35],
[36, 37, 38, 39, 40, 41, 42, 43, 44],
[45, 46, 47, 48, 49, 50, 51, 52, 53],
[54, 55, 56, 57, 58, 59, 60, 61, 62],
[63, 64, 65, 66, 67, 68, 69, 70, 71],
[72, 73, 74, 75, 76, 77, 78, 79, 80]])
>>> y = (x[np.ix_([8,6,4,2,0],[1,3,5,7,0])])
>>> y
array([[73, 75, 77, 79, 72],
[55, 57, 59, 61, 54],
[37, 39, 41, 43, 36],
[19, 21, 23, 25, 18],
[ 1, 3, 5, 7, 0]])

If you want to systematically learn numpy, it is recommended to read the official reference documents carefully, which can be consulted on its official website.

--

--

Jahid Hasan

Enthusiast of Data Science | Data Analyst | Machine Learning | Artificial intelligence | Deep Learning | Author || ps: https://msjahid.github.io/