How is numpy's fancy indexing implemented
Published: 2024-02-28 06:39:46

[NumPy's fancy indexing ](https://pythonkb.com/python-how-is-numpys-fancy-indexing-implemented/)allows you to select elements from an array using arrays of indices or boolean masks. It provides a powerful way to access and manipulate elements in arrays. Fancy indexing is implemented efficiently in NumPy, typically using C or Cython under the hood for optimized performance.

Let's go through five examples of fancy indexing and explain each step in detail:

### Example 1: Basic Fancy Indexing
```python
import numpy as np

# Creating an array
arr = np.array([1, 2, 3, 4, 5])

# Fancy indexing
indices = [0, 2, 4]
result = arr[indices]

print(result)
```

**Explanation:**
1. We import the NumPy library.
2. We create an array `arr` containing `[1, 2, 3, 4, 5]`.
3. We define `indices` as `[0, 2, 4]`, indicating the indices we want to select.
4. Using fancy indexing `arr[indices]`, we select elements at indices `0`, `2`, and `4`.
5. The selected elements `[1, 3, 5]` are returned as `result`.

**Output:** `[1 3 5]`

### Example 2: Fancy Indexing with 2D Array
```python
import numpy as np

# Creating a 2D array
arr = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])

# Fancy indexing
indices = [0, 2]
result = arr[:, indices]

print(result)
```

**Explanation:**
1. We create a 2D array `arr`.
2. `arr` is:
   ```
   [[1 2 3]
    [4 5 6]
    [7 8 9]]
   ```
3. We define `indices` as `[0, 2]`, indicating the columns we want to select.
4. Using fancy indexing `arr[:, indices]`, we select all rows (`:`) and columns at indices `0` and `2`.
5. The selected columns `[[1 3] [4 6] [7 9]]` are returned as `result`.

**Output:**
```
[[1 3]
 [4 6]
 [7 9]]
```

### Example 3: Fancy Indexing with Boolean Mask
```python
import numpy as np

# Creating an array
arr = np.array([1, 2, 3, 4, 5])

# Boolean mask
mask = np.array([True, False, True, False, True])
result = arr[mask]

print(result)
```

**Explanation:**
1. We create an array `arr` containing `[1, 2, 3, 4, 5]`.
2. We define a boolean mask `mask` where `True` indicates the elements to be selected.
3. Using fancy indexing `arr[mask]`, we select elements where the mask is `True`.
4. The selected elements `[1, 3, 5]` are returned as `result`.

**Output:** `[1 3 5]`

### Example 4: Combining Fancy Indexing and Slicing
```python
import numpy as np

# Creating a 2D array
arr = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])

# Fancy indexing with slicing
indices = [0, 2]
result = arr[:2, indices]

print(result)
```

**Explanation:**
1. We create a 2D array `arr`.
2. We define `indices` as `[0, 2]`.
3. Using fancy indexing and slicing `arr[:2, indices]`, we select the first two rows and columns at indices `0` and `2`.
4. The selected elements `[[1 3] [4 6]]` are returned as `result`.

**Output:**
```
[[1 3]
 [4 6]]
```

### Example 5: Fancy Indexing with Repeating Indices
```python
import numpy as np

# Creating an array
arr = np.array([1, 2, 3, 4, 5])

# Fancy indexing with repeating indices
indices = [0, 0, 2, 2, 4, 4]
result = arr[indices]

print(result)
```

**Explanation:**
1. We create an array `arr` containing `[1, 2, 3, 4, 5]`.
2. We define `indices` with repeating indices.
3. Using fancy indexing `arr[indices]`, NumPy repeats the elements at specified indices.
4. The selected elements `[1, 1, 3, 3, 5, 5]` are returned as `result`.

**Output:** `[1 1 3 3 5 5]`

These examples demonstrate the versatility and power of fancy indexing in NumPy, allowing you to select elements from arrays in various ways to suit your needs.