Привет! Мы уже научились создавать массивы и получать информацию о них. Теперь пришло время научиться извлекать данные из массивов — это одна из самых частых операций в NumPy.
В этой статье мы разберём:
- Индексацию одномерных массивов
- Индексацию многомерных массивов
- Срезы (slicing)
- Булеву индексацию
- Views и копии
- Что нужно знать перед началом
- Основная часть
- Индексация одномерных массивов
- Индексация двумерных массивов
- Срезы (slicing) одномерных массивов
- Срезы многомерных массивов
- Булева индексация
- Булева индексация в двумерных массивах
- Views vs копии
- Fancy indexing (индексация списком)
- Задачи для закрепления
- Нюансы и подводные камни
- Частые ошибки и как их избежать
- Шпаргалка
- Заключение
- КВИЗ
- Что дальше?
Что нужно знать перед началом
Для этого урока тебе понадобится:
- Установленный NumPy
- Базовое понимание массивов
Совет: Индексация в NumPy работает так же, как в списках Python, но с дополнительными возможностями.
Основная часть
Индексация одномерных массивов
В одномерных массивах индексация работает как в списках:
import numpy as np
arr = np.array([10, 20, 30, 40, 50])
print(arr[0]) # 10
print(arr[2]) # 30
print(arr[-1]) # 50 (последний элемент)
print(arr[-2]) # 40Совет: Индексация начинается с 0. Отрицательные индексы отсчитываются с конца.
Индексация двумерных массивов
В двумерных массивах индексы разделяются запятой: [строка, столбец].
arr = np.array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
print(arr[0, 0]) # 1 (первая строка, первый столбец)
print(arr[1, 2]) # 6 (вторая строка, третий столбец)
print(arr[2, 1]) # 8 (третья строка, второй столбец)
# Доступ к целой строке
print(arr[1]) # [4 5 6]
# Доступ к целому столбцу
print(arr[:, 1]) # [2 5 8]Совет: Двоеточие
:означает «все элементы по этому измерению».
Срезы (slicing) одномерных массивов
Срезы в NumPy работают как в списках:
arr = np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
print(arr[2:7]) # [2 3 4 5 6]
print(arr[:5]) # [0 1 2 3 4]
print(arr[5:]) # [5 6 7 8 9]
print(arr[::2]) # [0 2 4 6 8] (каждый второй)
print(arr[::-1]) # [9 8 7 6 5 4 3 2 1 0] (в обратном порядке)Совет: Срезы создают
view(представление), а не копию данных.
Срезы многомерных массивов
arr = np.array([[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12]])
# Первые две строки, все столбцы
print(arr[0:2, :])
# [[1 2 3 4]
# [5 6 7 8]]
# Все строки, столбцы 1-2
print(arr[:, 1:3])
# [[ 2 3]
# [ 6 7]
# [10 11]]
# Первые две строки, столбцы 1-2
print(arr[0:2, 1:3])
# [[2 3]
# [6 7]]
# Каждая вторая строка, каждый второй столбец
print(arr[::2, ::2])
# [[1 3]
# [9 11]]Совет: Синтаксис срезов:
[start:stop:step]для каждого измерения.
Булева индексация
Булева индексация позволяет выбирать элементы, удовлетворяющие условию.
arr = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
# Элементы больше 5
mask = arr > 5
print(mask) # [False False False False False True True True True True]
print(arr[mask]) # [ 6 7 8 9 10]
# Элементы чётные
print(arr[arr % 2 == 0]) # [2 4 6 8 10]
# Элементы между 3 и 7
print(arr[(arr > 3) & (arr < 7)]) # [4 5 6]Совет: Для сложных условий используй
&(И) и|(ИЛИ).
Булева индексация в двумерных массивах
arr = np.array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
# Элементы больше 4
print(arr[arr > 4]) # [5 6 7 8 9]
# Строки, где сумма > 10
rows = np.sum(arr, axis=1)
print(rows) # [6 15 24]
print(arr[rows > 10]) # [[4 5 6]
# [7 8 9]]Views vs копии
Срезы в NumPy создают view (представление), а не копию данных.
arr = np.array([1, 2, 3, 4, 5])
sub = arr[1:4]
sub[0] = 99
print(arr) # [1 99 3 4 5] (исходный массив изменился)
print(sub) # [99 3 4]Совет: Чтобы создать копию, используй
.copy().
arr = np.array([1, 2, 3, 4, 5])
sub = arr[1:4].copy()
sub[0] = 99
print(arr) # [1 2 3 4 5] (не изменился)
print(sub) # [99 3 4]Fancy indexing (индексация списком)
arr = np.array([10, 20, 30, 40, 50, 60])
# Индексация списком индексов
indices = [0, 2, 4]
print(arr[indices]) # [10 30 50]
# Индексация массивом индексов
indices = np.array([1, 3, 5])
print(arr[indices]) # [20 40 60]
# Двумерная индексация
arr2d = np.array([[1, 2], [3, 4], [5, 6]])
rows = [0, 2]
cols = [1, 0]
print(arr2d[rows, cols]) # [2 5]Задачи для закрепления
Задача 1. Извлеки элементы с индексами 1, 3, 5 из массива [10, 20, 30, 40, 50, 60].
Задача 2. Извлеки второй столбец из матрицы 3×3.
Задача 3. Извлеки подмассив 2×2 из центра матрицы 4×4.
Задача 4. Выбери все чётные числа из массива.
Задача 5. Измени форму массива с помощью срезов.
Ответы:
Задача 1.
import numpy as np
arr = np.array([10, 20, 30, 40, 50, 60])
result = arr[[1, 3, 5]]
print(result) # [20 40 60]Задача 2.
arr = np.array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
col = arr[:, 1]
print(col) # [2 5 8]Задача 3.
arr = np.array([[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12],
[13, 14, 15, 16]])
center = arr[1:3, 1:3]
print(center)
# [[ 6 7]
# [10 11]]Задача 4.
arr = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
evens = arr[arr % 2 == 0]
print(evens) # [2 4 6 8 10]Задача 5.
arr = np.arange(12).reshape(3, 4)
print(arr)
sub = arr[0:2, 1:3]
print(sub) # [[1 2]
# [5 6]]Нюансы и подводные камни
- Срезы создают
view, а не копию. Изменение среза изменяет исходный массив. - Булева индексация всегда создаёт копию. Изменение результата не влияет на оригинал.
- При использовании списка индексов (fancy indexing) создаётся копия.
arr[0:5]иarr[0:5].copy()— разное поведение.- В многомерных массивах
arr[1]иarr[1, :]дают одинаковый результат, но синтаксис может ввести в заблуждение. arr[:, 1]— это копия столбца, а неview. В отличие от строк.
Частые ошибки и как их избежать
Ошибка 1: Изменение среза меняет оригинал
Неправильно:
arr = np.array([1, 2, 3, 4, 5])
sub = arr[1:4]
sub[0] = 99
print(arr) # [1 99 3 4 5] — неожиданно!Правильно:
sub = arr[1:4].copy()
sub[0] = 99
print(arr) # [1 2 3 4 5]Ошибка 2: Индекс вне границ
Проверяй shape перед индексацией.
Ошибка 3: Путаница между arr[0, 1] и arr[0][1]
Для многомерных массивов используй arr[0, 1] — это быстрее и чище.
Шпаргалка
| Что нужно | Как пишется |
|---|---|
| Элемент (i, j) | arr[i, j] |
| Строка i | arr[i, :] |
| Столбец j | arr[:, j] |
| Срез строк | arr[1:5, :] |
| Срез столбцов | arr[:, 2:6] |
| Булева индексация | arr[arr > 5] |
| Копия среза | arr[1:4].copy() |
| Fancy indexing | arr[[0, 2, 4]] |
Заключение
Сегодня мы:
- Научились индексировать одномерные и многомерные массивы
- Использовали срезы для извлечения подмассивов
- Применяли булеву индексацию
- Поняли разницу между views и копиями





