Коротко
- Сравнение массива даёт маску — массив
True/Falseтой же формы:temps > 5. a[маска]возвращает элементы, где маскаTrue. Результат — одномерная копия.- Условия объединяют через
&(и),|(или),~(не), каждое условие — в скобках. Словаand,or,notс массивами не работают. a[маска] = значениеменяет только выбранные элементы.маска.sum()— сколькоTrue,маска.mean()— их доля;any()/all()— есть ли хоть один / все ли.
Синтаксис
mask = a > 0
a[mask] # или сразу a[a > 0]
a[(a > 0) & (a < 10)] # и
a[(a < 0) | (a > 10)] # или
a[~mask] # не
a[a < 0] = 0 # запись по маске
mask.sum(), mask.any(), mask.all()Примеры
# дневная температура за две недели
temps = np.array([3, -2, 5, 8, -1, 0, 12, 15, 9, -4, 6, 11, 14, 2])warm = temps > 5
print(warm)
temps[warm] # только элементы, где маска TrueВывод
[False False False True False False True True True False True True True False] array([ 8, 12, 15, 9, 6, 11, 14])
print(temps[(temps > 0) & (temps < 10)]) # и
print(temps[(temps < 0) | (temps > 12)]) # или
temps[~(temps > 5)] # неВывод
[3 5 8 9 6 2] [-2 -1 15 -4 14] array([ 3, -2, 5, -1, 0, -4, 2])
fixed = temps.copy()
fixed[fixed < 0] = 0 # отрицательные — в ноль
fixedВывод
array([ 3, 0, 5, 8, 0, 0, 12, 15, 9, 0, 6, 11, 14, 2])
a[a < 0] = 0 меняет массив на месте. Если нужно получить новый массив, не трогая старый, используйте np.where или np.clip.
print((temps < 0).sum()) # True считается как 1
print(np.count_nonzero(temps > 10))
print((temps > 10).mean()) # доля дней
print((temps > 20).any(), (temps > -10).all())Вывод
3 4 0.2857142857142857 False True
grid = np.array([[1, -2, 3],
[-4, 5, -6]])
grid[grid > 0] # результат всегда одномерныйВывод
array([1, 3, 5])
Подводные камни
and / or вместо & / |
Python пытается превратить весь массив в одно True или False и не может.
temps[(temps > 0) and (temps < 10)]Ошибка
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
Условия без скобок
У & и | приоритет выше, чем у > и <: a > 0 & a < 10 читается как a > (0 & a) < 10. Скобки вокруг каждого условия обязательны.
temps[temps > 0 & temps < 10] # & выполняется раньше сравненийОшибка
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()