In this tutorial, we will cover advance indexing of ndarray elements in the Python NumPy library.

The slicing in NumPy array is only **used to present a view **whereas advanced indexing always returns a **copy of the data**.

If you wish to select random numbers from different rows in an ndarray, and the items you want to pick are in no sequence, then we can use advance indexing concept. You will see in the code examples below that we will use advance indexing to pick random elements from different rows and columns of an ndarray.

## Types of Advance Indexing

Following are the types of Advance Indexing:

Now we will cover the above-mentioned types of advance indexing one by one.

## 1. Integer Indexing

With the help of the Integer Indexing mechanism, you can select any** arbitrary item based on the N-dimensional Index**. Also, each integer array is used to represent the number of indexes into that dimension.

At the times When the index consists of as many integer arrays as the dimensions of the target ndarray, then it becomes too straightforward.

### Example 1:

In the example given below, **one element of a specified column from each row** of ndarray object will be selected. Thus the **row index will contain all row numbers**, and the **column index will specify the element** to be selected. The code snippet for the same is as follows:

```
import numpy as np
x = np.array([[11, 28], [23, 84], [95, 56]])
print ("The array used for Integer Indexing")
print(x)
y = x[[0,1,2], [0,0,1]]
print("The Output is:")
print(y)
```

Output:

The array used for Integer Indexing

[[11 28]

[23 84]

[95 56]]

The Output is:

[11 23 56]

In the code above, while performing advance indexing and creating a new ndarray `y`

, for the ndarray `x`

, first we specify the **row numbers of all the rows to be picked** and then we **specify the index of the actual elements** of that row to be picked.

So the code `x[[0,1,2], [0,0,1]]`

means that rows to be picked are **0th row, 1st row and 2nd row** (represented by [0, 1, 2]) and then from 0th row pick the [0] index element, from 1st row pick [0] index element and from the 2nd row pick the [1] index element (represented by [0, 0, 1]).

### Example 2:

In the example given below, we will try to select the corner elements of ndarray. The code snippet for the same is as follows:

```
import numpy as np
x = np.array([[10, 81, 2], [3, 43, 35], [63, 72, 8], [92, 10, 11]])
# [10, 81, 2]
# [ 3, 43, 35]
# [62, 72, 8]
# [92, 10, 11]
# so corener elements are 10, 2, 92 and 11
print ('The array is:')
print (x)
# picking the 1st and last row
rows = np.array([[0], [3]])
# picking 0 index and 2nd index element from each row
cols = np.array([[0, 2], [0, 2]])
y = x[rows, cols]
print ('The corner elements of the array are:')
print (y)
```

Output:

The array is: [[10 81 2] [ 3 43 35] [63 72 8] [92 10 11]] The corner elements of the array are: [[10 2] [92 11]]

**Note:** You can combine the advanced and basic indexing using one slice (`:`

) or ellipsis (`…`

) with an index array.

### Example 3:

In our following example, we will use **slice for row and advanced index for column**. The result is the same as when slicing is used for both. But as you know, advanced index results in creation of a new copy of ndarray and may have different memory layout, s we should be careful while using them together. Let us take a look at the code snippet given below:

```
import numpy as np
x = np.array([[11, 1, 12], [31, 4, 15], [6, 37, 8], [91, 10, 11]])
print("The array is:")
print(x)
# Using basic slicing
z = x[1:4, 1:3]
print('After slicing the array becomes:')
print(z)
# using advanced indexing for column
y = x[1:4, [1,2]]
print('After Slicing using advance index for column:')
print(y)
```

Output:

The array is: [[11 1 12] [31 4 15] [ 6 37 8] [91 10 11]] After slicing the array becomes: [[ 4 15] [37 8] [10 11]] After Slicing using advance index for column: [[ 4 15] [37 8] [10 11]]

## 2. Boolean Indexing

Boolean Indexing is a kind of advanced indexing that is used when we want to pick elements from an ndarray based on some condition using comparison operators or some other operator.

### Example 1:

In the code example given below, **items greater than 11** are returned as a result of Boolean indexing:

```
import numpy as np
x = np.array([[11, 51, 2],[23, 24, 5], [16, 47, 8] ,[91, 10, 11]])
print("The array is:")
print(x)
# Now we will print the items greater than 11
print("The items greater than 11 are:")
print(x[x>11])
```

Output:

The array is: [[11 51 2] [23 24 5] [16 47 8] [91 10 11]] The items greater than 6 are: [51 23 24 16 47 91]

Just like we did in the code example above we can also use different operators to look for elements less than, equal to or greater than a given number.

### Example 2: Remove ‘Not a Number’ Values

To omit **Not A Number (NaN)** you can use `~`

(**complement operator**). The code snippet for the same is given below:

```
import numpy as np
a = np.array([np.nan, 1, 12, np.nan, 3, 41, 54])
print("After omitting NaN the output array is :")
print (a[~np.isnan(a)])
```

Output:

After omitting NaN the output array is : [ 1. 12. 3. 41. 54.]

### Example 3: Remove Non-Complex Numbers

With the code example given below, you will understand how to **filter out the non-complex elements** from an array:

```
import numpy as np
a = np.array([1, 2+6j, 5, 3.5+5j])
print("After Filtering the non-complex numbers :")
print (a[np.iscomplex(a)])
```

Output:

After Filtering the non-complex numbers : [2. +6.j 3.5+5.j]