Aman Gupta
Posted on January 10, 2021
In this blog, we are talking about different ways of indexing array in NumPy which are amazing.
Basic Slicing and Indexing
So here from basic slicing and indexing we are talking about pythons basic concept of slicing and indexing which is similar as python built-in data type tuple
, list
and str
.
for accessing a single element from numpy array we can do it by passing passing each dimension’s index saperated by ,
in [ ]
, because numpy support multi-dimension indexing.
for example: a[1,2] = a[1][2]
.
we can pass value of index either positive start with 0 (which is the first element) or negative where -1 mean the last element of the array.
For accessing more then one element , we can use python's standers slicing syntex per dimension basis all sapetared with ,
in square bracket.
Basic slice syntex in
i:j:k
where i is starting index, j is stoping index and k is the steps.
>>> import numpy as np
>>> ## Accessing a single element:
>>> # 1. from 1-D array:
>>> arr = np.arange(10)
>>> arr[0]
0
>>> arr[-2]
8
>>> #2. from 2-D array:
>>> nd_arr = np.array([[1,2,3],
... [4,5,6],
... [7,8,9]])
>>> nd_arr[1,2]
6
>>> nd_arr[-1,2]
9
>>> ## accessing more then one element:
>>> # for 1-D array:
>>> arr[1:5:2]
array([1, 3])
>>> # for 2-D array:
>>> nd_arr[0:2:1,:]
array([[1, 2, 3],
[4, 5, 6]])
>>> #this can also be achieved by '...':
>>> nd_arr[0:2:1,...]
array([[1, 2, 3],
[4, 5, 6]])
Ellipsis ('...')
expands to the number of :
objects needed for the selection tuple to index all dimensions. In most cases, this means that length of the expanded selection tuple is arr.ndim
. There may only be a single ellipsis present.
Ellipsis
is a python built-in Constant type which used mostly in conjunction with extended slicing syntax for user-defined container data types.
Advance Indexing in Numpy array
advance indexing mean when the selection object is non-tuple object , an ndarray of int or bool , or tuple with al least one sequence object with int or bool data types.
There are two types of advance indexing, one is integer and another is boolean.
In numpy,
Advanced Indexing
always returns a copy of data whilebasic slicing
returns a view.One most important thing is that The definition of advanced indexing means that
x[(1,2,3),]
is fundamentally different thanx[(1,2,3)]
. The latter is equivalent tox[1,2,3]
which will trigger basic selection while the former will trigger advanced indexing. Be sure to understand why this occurs.Also recognize that
x[[1,2,3]]
will trigger advanced indexing
Integer array Indexing
Integer array indexing allows selection of arbitrary items in the array based on their N-dimensional index. Each integer array represents a number of indexes into that dimension.
Purely integer array indexing
When the index consists of as many integer arrays as the array being indexed has dimensions, the indexing is straight forward, but different from slicing.
>>> #Example:
>>> x = np.array([[1, 2], [3, 4], [5, 6]])
>>> x[[0, 1, 2], [0, 1, 0]]
array([1, 4, 5])
>>> #Example
>>> x = np.array([[ 0, 1, 2],
... [ 3, 4, 5],
... [ 6, 7, 8],
... [ 9, 10, 11]])
>>> rows = np.array([[0, 0],[3, 3]], dtype=np.intp)
>>> columns = np.array([[0, 2],[0, 2]], dtype=np.intp)
>>> x[rows, columns]
array([[ 0, 2],
[ 9, 11]])
Advance Indexes always broadcasted and iterated as one. The result we get is similar dimention of broadcasted result.
in above example we broadcast in rows and column but in nympy there are one function ix_
which help this broadcasting.
>>> #Example
>>> x = np.array([[ 0, 1, 2],
... [ 3, 4, 5],
... [ 6, 7, 8],
... [ 9, 10, 11]])
>>> rows = np.array([0, 3], dtype=np.intp)
>>> columns = np.array([0, 2], dtype=np.intp)
>>> x[np.ix_(rows, columns)]
array([[ 0, 2],
[ 9, 11]])
>>> # if we don't use `np.ix_` then result:
>>> x[rows, columns]
array([ 0, 11])
Combining advanced and basic indexing
When there is at least one slice (:)
, ellipsis (...)
or newaxis
in the index (or the array has more dimensions than there are advanced indexes), then the behaviour can be more complicated. It is like concatenating the indexing result for each advanced index element
>>> x[1:2,1:3]
array([[4, 5]])
>>> x[1:2,[1,2]]
array([[4, 5]])
Boolean array Indexing
This types of indexing occurs when the selection object is the array of Boolean, such as returned from comparison operator.
if the dimension of selection onject is same as the array then it returns a 1-D array filled with all result corresponding to the True
value . The search order will be row-major
, C-style .
If obj has
True
values at entries that are outside of the bounds ofx
, then anindex error
will be raised. Ifobj
is smaller thanx
it is identical to filling it withFalse
.
>>> #Example:
>>> x = np.array([[1., 2.], [np.nan, 3.], [np.nan, np.nan]])
>>> x[~np.isnan(x)]
array([1., 2., 3.])
>>> #Example:
>>> x = np.array([1., -1., -2., 3])
>>> x[x < 0] += 20
>>> x
array([ 1., 19., 18., 3.])
>>> #Example : use with basic indexing
>>> x = np.array([[0, 1], [1, 1], [2, 2]])
>>> rowsum = x.sum(-1)
>>> x[rowsum <= 2, :]
array([[0, 1],
[1, 1]])
>>> #Example : use with np.ix_
>>> x = np.array([[ 0, 1, 2],
... [ 3, 4, 5],
... [ 6, 7, 8],
... [ 9, 10, 11]])
>>> rows = (x.sum(-1) % 2) == 0
>>> columns = [0, 2]
>>> x[np.ix_(rows, columns)]
array([[ 3, 5],
[ 9, 11]])
Something More intresting then above:
Field Access:
If the ndarray object is a structured array the fields of the array can be accessed by indexing the array with strings, dictionary-like.
Indexing x['field-name']
returns a new view to the array.
If the accessed field is a sub-array, the dimensions of the sub-array are appended to the shape of the result.
>>> x = np.zeros((2,2), dtype=[('a', np.int32), ('b', np.float64,(3,3))])
>>> x['a']
array([[0, 0],
[0, 0]])
>>> x['b']
array([[[[0., 0., 0.],
[0., 0., 0.],
[0., 0., 0.]],
[[0., 0., 0.],
[0., 0., 0.],
[0., 0., 0.]]],
[[[0., 0., 0.],
[0., 0., 0.],
[0., 0., 0.]],
[[0., 0., 0.],
[0., 0., 0.],
[0., 0., 0.]]]])
Flat Iterator indexing
x.flat
returns an iterator that will iterate over the entire array (in C-contiguous style with the last index varying the fastest). This iterator object can also be indexed using basic slicing or advanced indexing as long as the selection object is not a tuple. This should be clear from the fact that x.flat is a 1-dimensional view. It can be used for integer indexing with 1-dimensional C-style-flat indices
. The shape of any returned array is therefore the shape of the integer indexing object.
>>> x = np.arange(1, 7).reshape(2, 3)
>>> x
array([[1, 2, 3],
[4, 5, 6]])
>>> x.flat[3]
4
>>> x.T
array([[1, 4],
[2, 5],
[3, 6]])
>>> x.T.flat[3]
5
>>> type(x.flat)
numpy.flatiter
>>> #assignment example
>>> x.flat = 3
>>> x
array([[3, 3, 3],
[3, 3, 3]])
>>> #assignment example
>>> x.flat[[1,4]] = 1
>>> x
array([[3, 1, 3],
[3, 1, 3]])
Posted on January 10, 2021
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.