Продвинутое индексирование и срезы

Продвинутое индексирование и срезы (slicing) в NumPy предоставляют мощные средства для работы с массивами, позволяя выбирать, изменять и анализировать данные гибкими и эффективными способами. Это особенно важно при работе с многомерными массивами, где нужно выбирать элементы не по одной оси, а по нескольким.

Основы индексирования и срезов

Простое индексирование

NumPy поддерживает стандартное индексирование массивов, как и в обычных списках Python.

import numpy as np

# Создаем массив
a = np.array([10, 20, 30, 40, 50])

# Доступ к элементу по индексу
element = a[2]  # 30

# Индексирование с конца
last_element = a[-1]  # 50

Для многомерных массивов:

b = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])

# Доступ к элементу в 1-й строке, 2-м столбце
element = b[0, 1]  # 2

# Доступ к строке
row = b[1]  # array([4, 5, 6])

Срезы (Slicing)

Срезы позволяют выбрать подмножество массива с помощью синтаксиса [start:stop:step].

# Выбор среза
slice_a = a[1:4]  # array([20, 30, 40])

# Шаг среза
slice_b = a[::2]  # array([10, 30, 50])

# Обратный порядок
reverse_a = a[::-1]  # array([50, 40, 30, 20, 10])

Для многомерных массивов:

# Выбор среза по строкам и столбцам
slice_c = b[0:2, 1:3]  # array([[2, 3], [5, 6]])

Продвинутое индексирование

Продвинутое индексирование позволяет выбирать элементы массива с помощью массивов индексов или булевых масок.

Целочисленное индексирование

С помощью массивов индексов можно выбирать отдельные элементы или целые строки и столбцы.

# Создаем массив
c = np.array([10, 20, 30, 40, 50])

# Индексирование по массиву индексов
indices = [1, 3, 4]
selected_elements = c[indices]  # array([20, 40, 50])

# Для многомерных массивов
d = np.array([[1, 2], [3, 4], [5, 6]])

# Выбор элементов по индексам
selected_elements_2d = d[[0, 1], [1, 0]]  # array([2, 3])

Булевое индексирование

Булевое индексирование позволяет выбирать элементы, удовлетворяющие определенному условию.

# Создаем массив
e = np.array([1, 2, 3, 4, 5])

# Булевая маска
mask = e > 3

# Выбор элементов с использованием маски
selected_elements = e[mask]  # array([4, 5])

# Изменение элементов с использованием булевого индексирования
e[mask] = 0  # array([1, 2, 3, 0, 0])

Для многомерных массивов:

# Создаем массив
f = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])

# Булевая маска
mask_2d = f > 4

# Применение маски
selected_elements_2d = f[mask_2d]  # array([5, 6, 7, 8, 9])

Комбинирование индексирования и срезов

NumPy позволяет комбинировать простое индексирование, срезы и продвинутое индексирование в одном выражении.

# Создаем массив
g = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])

# Комбинируем срезы и индексирование
result = g[1:, [0, 2]]  # array([[4, 6], [7, 9]])

# Выбор всех элементов, кроме последней строки, в которых значения больше 2
result_2 = g[:-1, g[0, :] > 2]  # array([[3], [6]])

Индексирование с помощью np.ix_

Функция np.ix_ позволяет генерировать массивы индексов для выборки элементов в нескольких осях одновременно.

# Создаем массив
h = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])

# Используем np.ix_ для индексации
rows = np.array([0, 2])
cols = np.array([1, 2])
result = h[np.ix_(rows, cols)]
print(result)
# array([[2, 3],
#        [8, 9]])

Изменение элементов с использованием индексирования

NumPy позволяет изменять элементы массива, используя индексы и срезы.

# Создаем массив
i = np.array([1, 2, 3, 4, 5])

# Изменяем элементы с использованием индексов
i[[0, 2, 4]] = 10
print(i)  # array([10,  2, 10,  4, 10])

# Изменяем элементы с использованием булевого индексирования
i[i > 4] = 0
print(i)  # array([0, 2, 0, 4, 0])

Для многомерных массивов:

# Создаем массив
j = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])

# Изменяем элементы по маске
j[j > 5] = -1
print(j)
# array([[ 1,  2,  3],
#        [ 4,  5, -1],
#        [-1, -1, -1]])

Индексация с помощью np.take и np.put

Функции np.take и np.put обеспечивают дополнительную гибкость при работе с индексами.

np.take

Функция np.take извлекает элементы массива по указанным индексам.

# Создаем массив
k = np.array([10, 20, 30, 40, 50])

# Извлечение элементов по индексам
result = np.take(k, [0, 2, 4])
print(result)  # array([10, 30, 50])

np.put

Функция np.put позволяет заменить элементы массива по указанным индексам.

# Создаем массив
l = np.array([10, 20, 30, 40, 50])

# Замена элементов по индексам
np.put(l, [0, 2, 4], [100, 300, 500])
print(l)  # array([100,  20, 300,  40, 500])

Заключение

Продвинутое индексирование и срезы в NumPy позволяют эффективно и гибко работать с массивами любой размерности. Эти техники необходимы для работы с большими объемами данных, их фильтрации, изменении и анализе. Опытное владение этими инструментами значительно ускоряет разработку и улучшает качество анализа данных в научных и инженерных задачах.

Last updated