NumPy: массивы, форма и индексация

Продвинутая индексация: булевы маски и целочисленные массивы индексов

Содержание курса

В прошлом уроке мы выбирали элементы, строки и столбцы через целочисленный индекс и срезы — то есть всегда явно указывали позиции. Сейчас подход меняется: вместо «возьми третий элемент» мы будем говорить «возьми все элементы, которые больше нуля». Для этого нужен новый инструмент — булева маска.

Булева маска: создание сравнительными операциями

Когда вы пишете arr > 3, NumPy не возвращает один True или False — он проходит по каждому элементу массива и проверяет условие отдельно. Результат — новый массив того же shape, но с dtype bool.

import numpy as np

arr = np.array([1, 2, 3, 4, 5])
mask = arr > 3
print(mask)        # [False False False  True  True]
print(mask.shape)  # (5,)
print(mask.dtype)  # bool

Это работает со всеми шестью операторами сравнения: ==, !=, <, >, <=, >=. Каждый из них применяется поэлементно и возвращает булев массив.

print(arr == 3)   # [False False  True False False]
print(arr != 3)   # [ True  True False  True  True]
print(arr <= 2)   # [ True  True False False False]

Для двумерного массива механика та же — shape маски совпадает с shape исходника:

matrix = np.array([[1, 5], [3, 7]])
print(matrix >= 5)
# [[False  True]
#  [False  True]]
print((matrix >= 5).shape)  # (2, 2)

Маска — это полноценный ndarray. Её можно сохранить в переменную, проверить shape и dtype, передать дальше. На этом шаге мы только строим маску: какие позиции удовлетворяют условию. Что с ней делать дальше — отбирать элементы или изменять их — разберём в следующих разделах.