Нашли ошибку?
среднийNumPy 2.5.3

Универсальные функции (ufunc)

Математические функции, которые применяются к каждому элементу со скоростью C, и их методы reduce, accumulate, outer.

Нужно знать:Арифметика с массивамиБазовые агрегации

Содержание статьи

Коротко

  • ufunc (universal function) — функция, которая применяется к каждому элементу массива; цикл выполняется внутри NumPy.
  • Одноместные: sqrt, exp, log, log10, abs, sin… Двуместные: add, multiply, maximum, minimum… Все операторы +, * — тоже ufunc.
  • np.maximum(a, b) выбирает большее из двух массивов поэлементно, а np.max(a) ищет максимум внутри массива.
  • У двуместных ufunc есть методы: reduce (свернуть), accumulate (нарастающий итог), outer (все пары), at (на месте по индексам).
  • Параметры out= и where= позволяют писать в готовый массив и считать только там, где условие истинно.
  • Функции модуля math с массивами не работают — берите аналоги из np.

Синтаксис

np.sqrt(a), np.exp(a), np.log(a), np.abs(a)
np.maximum(a, b), np.minimum(a, b)      # поэлементно из двух
np.add.reduce(a)          # = a.sum()
np.add.accumulate(a)      # = a.cumsum()
np.multiply.outer(a, b)   # все пары: форма (len(a), len(b))
np.add.at(a, idx, 1)      # прибавить по индексам с повторами
np.sqrt(a, out=res, where=a >= 0)

Параметры

ПараметрЧто делаетПо умолчанию
outмассив, куда записать результат (вместо создания нового)None
whereмаска: считать только там, где True; в остальных местах out не меняетсяTrue
dtypeтип, в котором вести вычислениеNone

Примеры

Функции одного аргумента
x = np.array([1.0, 4.0, 9.0, 16.0])
print(np.sqrt(x))
print(np.log10(x))
np.abs(np.array([-3, 0, 2]))
Вывод
[1. 2. 3. 4.]
[0.         0.60205999 0.95424251 1.20411998]
array([3, 0, 2])
maximum против max
today = np.array([12, 18, 9])
yesterday = np.array([15, 11, 9])
print(np.maximum(today, yesterday))  # поэлементно из двух массивов
print(np.max(today))                 # максимум внутри одного массива
np.maximum(today, 10)                # не меньше 10
Вывод
[15 18  9]
18
array([12, 18, 10])
reduce и accumulate
deposits = np.array([100, 250, 50, 300])
print(np.add.reduce(deposits))       # то же, что sum
print(np.add.accumulate(deposits))   # то же, что cumsum
np.maximum.accumulate(np.array([3, 1, 4, 1, 5, 2]))   # максимум «на текущий момент»
Вывод
700
[100 350 400 700]
array([3, 3, 4, 4, 5, 5])
outer: все пары
np.multiply.outer(np.arange(1, 5), np.arange(1, 6))   # таблица умножения 4 × 5
Вывод
array([[ 1,  2,  3,  4,  5],
       [ 2,  4,  6,  8, 10],
       [ 3,  6,  9, 12, 15],
       [ 4,  8, 12, 16, 20]])
Вычислить только где можно
x = np.array([4.0, -1.0, 9.0])
np.sqrt(x, out=np.full(3, np.nan), where=x >= 0)      # корень только из неотрицательных
Вывод
array([ 2., nan,  3.])

Без out= элементы, где условие ложно, остались бы неинициализированными — поэтому where= всегда используют вместе с out=.

Подводные камни

log и sqrt от недопустимых значений

Логарифм нуля даёт -inf, логарифм и корень отрицательного — nan. Исключения нет, только RuntimeWarning.

Логарифм нуля и отрицательного
np.log(np.array([1.0, 0.0, -1.0]))
Вывод
RuntimeWarning: divide by zero encountered in log
RuntimeWarning: invalid value encountered in log
array([  0., -inf,  nan])

math.sqrt вместо np.sqrt

Функция math с массивомошибка: TypeError
import math
math.sqrt(np.array([4.0, 9.0]))      # math работает только с одним числом
Ошибка
TypeError: only 0-dimensional arrays can be converted to Python scalars