# Numpy Fancy Indexing

In earlier section, we discussed `indexing` `(arr[2])` and `slicing` `(arr[:5])` to fetch a single element and subset of array, respectively.

In *Fancy Indexing*, we pass array of indices instead of single scalar(numbers) to fetch elements at different index points. Remember that the shape of the output depends on the shape of the *index arrays* rather than the shape of the *array being indexed*

## 1. FANCY INDEXING 101

Let’s go through some examples to understand this concept

```python
import numpy as np

rand = np.random.RandomState(42)

# creating 1d array for demonstration
arr1 = rand.randint(100, size=10)
print(f"1D array:\n{arr1}")

#creating 2d array for demonstration
arr2 = rand.randint(100, size=(3,5))
print(f"\n2D array:\n{arr2}") 
```

```
1D array:
[51 92 14 71 60 20 82 86 74 74]

2D array:
[[87 99 23  2 21]
 [52  1 87 29 37]
 [ 1 63 59 20 32]]
```

### 1.1. Case A

#### a. 1D Array

For 1D array, let’s suppose we want to access elements at index position of `0`, `4` and `-1`

```python
# method 1
arr1[0],arr1[4],arr1[-1]
```

```
(51, 60, 74)
```

```python
# method 2
i = np.array([0,4,-1])
arr1[i]
```

```
array([51, 60, 74])
```

#### b. 2D Array

For 2D array, we need to provide the index position at both axis levels. Here is an example, where we are giving the index position at both row and column. We wan to get first row, first item; second row, second item; and third row, third item:

```python
row_ind = np.array([0,1,2])
col_ind = np.array([0,1,2])
arr2[row_ind,col_ind]
```

```
array([87,  1, 59])
```

As you can see in above example that the shape of output depends on the shape of *index array* and not the shape of *array being indexed*, which is 2D array in this example

### 1.2. Case B

We will go a step forward and discuss the cases where we need to fetch multiple items from each row, which in return gives us a 2D array in the output

```python
# first, let's change the shape of row_ind
row_ind = row_ind.reshape(3,1)
print(row_ind)

# slicing the arr2
print(arr2[row_ind, col_ind])
```

```
[[0]
 [1]
 [2]]
[[87 99 23]
 [52  1 87]
 [ 1 63 59]]
```

## 2. COMBINED INDEXING

In this section, we will combine simple indexing technique with fancy indexing.

### 2.1. Case A

\*\*Simple & Fancy indexing: \*\*Let’s fetch `0`, `3` and `-1` indexed items in the column, from the first row `0` of `arr2`

```python
arr2[0,[0,3,-1]]
```

```
array([87,  2, 21])
```

### 2.2. Case B

**Fancy Indexing & Slicing:** Let’s fetch `0`, `3` and `-1` indexed item in the column, from the first `0` and second `1` row of `arr2`

```python
arr2[:2,[0,3,-1]] 
```

```
array([[87,  2, 21],
       [52, 29, 37]])
```

Let’s fetch `0`, `3` and `-1` indexed item in the column, from every other row of `arr2`

```python
arr2[::2,[0,3,-1]] 
```

```
array([[87,  2, 21],
       [ 1, 20, 32]])
```

### 2.3. Case C

\*\*Boolean Masking and Slicing: \*\*If you haven’t covered boolean masking then you can just skip this section and come back at it again, later.

Let’s suppose, in every other row, we want to fetch all the column elements whose index position is `True` (`1`) in the provided array.

```python
mask = np.array([1,0,1,0,1], dtype=bool)
arr2[::2,mask]
```

```
array([[87, 23, 21],
       [ 1, 59, 32]])
```

## 3. MODIFYING VALUES

In this section, we will use the fancy indexing techniques to replace the values in the array.

Let suppose, for our 1D array `arr1`, we want to modify the `0`, `4` and `-1` values to `0`

```python
print(f"arr1 before modification: \n{arr1}")

# defining index position where modification needed
i = np.array([0,4,-1])

# modifying the value
arr1[i] = 0

# printing the results
print(f"arr1 after modification: \n{arr1}")
```

```
arr1 before modification: 
[51 92 14 71 60 20 82 86 74 74]
arr1 after modification: 
[ 0 92 14 71  0 20 82 86 74  0]
```

In addition to setting the value to single number (`0` in above example), we can also use operations like, `+=`, `-=` etc

Using the same methods, we can also modify the values in 2D array. Let modify the first and last column values of all rows to `0`

```python
print(f"arr2 before modification: \n{arr2}")

# modifiyng values
arr2[:,[0,-1]] = 0
print(f"arr2 after modification: \n{arr2}")
```

```
arr2 before modification: 
[[87 99 23  2 21]
 [52  1 87 29 37]
 [ 1 63 59 20 32]]
arr2 after modification: 
[[ 0 99 23  2  0]
 [ 0  1 87 29  0]
 [ 0 63 59 20  0]]
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://codingnotes.gitbook.io/coding_notes/coding/numpy/numpy-fancy-indexing.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
