|
Базовые математические функции
На этом занятии
рассмотрим основные математические функции пакета NumPy, увидим, как
они используются совместно с массивами.
Функции sum, mean, min и max
Итак, очень
часто на практике требуется вычислять сумму значений элементов массива, их
среднее значение, а также находить минимальные и максимальные значения. Для
этих целей в NumPy существуют
встроенные функции, выполняющие эти действия и сейчас мы посмотрим как они
работают. Пусть, как всегда, у нас имеется одномерный массив:
a = np.array([ 1, 2, 3, 10, 20, 30])
Вычислим сумму,
среднее значение и найдем максимальное и минимальное значения:
a.sum() # 66
a.mean() # 11.0
a.max() # 30
a.min() # 1
Как видите, все
достаточно просто. Тот же самый результат будет получен и при использовании
многомерных массивов. Например:
a.resize(3, 2)
a.sum() # 66
Но, если
требуется вычислить сумму только по какой-то одной оси, то ее можно явно
указать дополнительным параметром:
a.sum(axis=0) # array([24, 42])
a.sum(axis=1) # array([ 3, 13, 50])
Точно также
работают и остальные три функции, например:
a.max(axis=0) # array([20, 30])
a.min(axis=1) # array([ 1, 3, 20])
Базовые математические функции
Все те же самые
операции и многие другие можно выполнять через функции пакета NumPy, а не через
методы массива. Вот список основных из них:
Название
|
Описание
|
np.abs(x)
|
Вычисление
модуля от аргумента(ов)x; xможет быть
числом, списком или массивом.
|
np.amax(x)
|
Нахождение
максимального значения от аргумента(ов)x
|
np.amin(x)
|
Нахождение
минимального значения от аргумента(ов)x
|
np.argmax(x)
|
Нахождение
индекса максимального значения дляx.
|
np.argmin(x)
|
Нахождение
индекса минимального значения дляx.
|
np.around(x)
|
Округление
до ближайшего целого.
|
np.mean(x)
|
Вычисление
среднего значения.
|
np.log(x)
|
Вычисление
натурального логарифма.
|
np.log2(x)
|
Вычисление
логарифма по основанию 2.
|
np.log10(x)
|
Вычисление
логарифма по основанию 10.
|
Предположим,
имеется массив:
a = np.array([-1, 1, 5, -44, 32, 2])
тогда для
вычисления модулей значений его элементов можно записать команду:
np.abs(a) # array([ 1, 1, 5, 44, 32, 2])
На выходе
получаем новый массив с абсолютными величинами. То же самое будет, если на вход
подать обычный список значений:
np.abs([-1, 1, 5, -44, 32, ])# array([ 1, 1, 5, 44, 32])
или просто
число:
Эти примеры
демонстрируют разные типы входных данных: массив, список, число. Все это
допустимо использовать в математических функциях.
Остальные
функции работают по аналогии, например:
np.amax(a) # 32
np.log(a) # array([nan, 0. , 1.60943791, nan, 3.4657359,0.69314718])
np.around(0.7) # 1.0
Функции amin, amax, mean, argmax, argmin, при работе с
многомерными матрицами, могут делать вычисления по строго определенной оси.
Например:
a.resize(2, 3)
np.amax(a, axis=0) # array([-1, 32, 5])
np.argmax(a, axis=1) # array([2, 1], dtype=int32)
И так далее.
Тригонометрические функции
Конечно, любой
состоятельный математический пакет должен иметь в своем составе
тригонометрические функции и NumPyздесь не исключение. Наиболее
употребительные из них приведены в следующей таблице:
Название
|
Описание
|
np.sin(x)
|
Вычисление
синуса угла x (в радианах);
xможет быть
числом, списком, массивом (это правило распространяется на все функции этой
таблицы).
|
np.cos(x)
|
Вычисление
косинуса угла(ов) x.
|
np.tan(x)
|
Вычисление
тангенса угла(ов) x.
|
np.arccos(x)
|
Арккосинус
угла(ов) x.
|
np.arcsin(x)
|
Арксинус
угла(ов) x.
|
np.arctan(x)
|
Арктангенс
угла(ов) x.
|
Их использование
также вполне очевидно. На входе они могут принимать массив, список или число.
Если это угол, то он представляется в радианах. Например:
a = np.linspace(0, np.pi, 10)
res1 = np.sin(a) # возвращает массив синусов углов
np.sin(np.pi/3)
np.cos([0, 1.57, 3.17])
res2 = np.cos(a) # возвращает массив косинусов углов
np.arcsin(res1) # возвращает арксинусы от значений res1
Причем, все эти
функции работают быстрее аналогичных функций языка Python. Поэтому, при
использовании библиотеки NumPy предпочтение лучше отдавать именно ей,
а не языку Python при
тригонометрических вычислениях.
Функции генерации псевдослучайных чисел
Название
|
Описание
|
random.rand()
|
Генерация
чисел с равномерным законом распределения
|
np.random.randint()
|
Генерация
целых чисел с равномерным законом распределения
|
np.random.randn()
|
Генерация
нормальных случайных значений
|
np.random.seed()
|
Установка
начального состояния генератора
|
Во многих
программах требуется генерировать случайные значения и в NumPy для этого
имеется специальный модуль random с богатым функционалом. Конечно,
совершенно случайные величины получить невозможно, поэтому придумываются
различные «хитрости» для их генерации и правильнее их называть –
псевдослучанйыми числами.
В самом простом
случае, функция rand() позволяет получать случайные числа в диапазоне от
0 до 1:
np.random.rand() # вещественное случайное число от 0 до 1
Если требуется
получить массив из таких чисел, то можно указать это через первый аргумент:
np.random.rand(5) # array([0.78191696, 0.66581136, 0.46458873, 0.76416839, 0.28206656])
Для получения
двумерных массивов – два аргумента:
np.random.rand(2, 3) # массив 2x3
И так далее.
Можно создавать любые многомерные массивы из случайных величин.
Если требуется
генерировать целые случайные значения, то используется функция randint():
np.random.randint(10) # генерация целых чисел в диапазоне [0; 10)
np.random.randint(5, 10)# генерация в диапазоне [5; 10)
Для получения
массива из таких случайных чисел дополнительно следует указать параметр size, следующим
образом:
np.random.randint(5, size=4) # array([3, 1, 1, 4])
np.random.randint(1, 10, size=(2, 5)) # матрица 2x5
Функции rand() и randint() генерируют
числа с равномерным законом распределения. Если нужно получать значения с
другими широко известными распределениями, то используются функции:
np.random.randn() # нормальная СВ с нулевым средним и единичной дисперсией
np.random.randn(5) # массив из пяти нормальных СВ
np.random.randn(2, 3) # матрица 2x3 из нормальных СВ
np.random.pareto(2.0, size=3) # распределение Паретто с параметром 2,0
np.random.beta(0.1, 0.3, size=(3, 3)) # бета-распределение с параметрами 0,1 и 0,3
Существуют и
другие функции для генерации самых разных распределений. Документацию по ним
можно посмотреть на официальном сайте пакета NumPy:
https://numpy.org/doc/stable/
По умолчанию,
все рассмотренные функции при каждом новом запуске генерируют разные числа.
Однако, иногда требуются одни и те же их реализации. Например, такой подход
часто используется для сохранения начальных случайных значений весов в
нейронных сетях. Для этого устанавливают некое начальное значение зерна (seed):
np.random.seed(13) # начальное значение генератора случайных чисел
и все
последующие запуски будут давать одну и ту же последовательность чисел,
например:
np.random.randint(10, size=10) # array([2, 0, 0, 6, 2, 4, 9, 3, 4, 2])
Причем, у вас
должны получиться такие же числа. Если запустим эту функцию еще раз, то будут
получены следующие 10 случайных чисел:
np.random.randint(10, size=10) # array([6, 5, 9, 4, 2, 0, 3, 5, 3, 6])
Но, установив
зерно снова в значение, например, 13:
числа начнут
повторяться:
np.random.randint(10, size=10) # array([2, 0, 0, 6, 2, 4, 9, 3, 4, 2])
np.random.randint(10, size=10) # array([6, 5, 9, 4, 2, 0, 3, 5, 3, 6])
Функции перемешивания элементов массива
Следующие две
функции:
np.random.shuffle() и np.random.permutation()
перемешивают
случайным образом элементы массива. Например, дан массив:
a = np.arange(10) # array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
И нам требуется
перетасовать его элементы. В самом простом случае, это делается так:
np.random.shuffle(a) # array([8, 7, 9, 6, 3, 4, 0, 2, 1, 5])
Причем, здесь
меняется сам массив a. Если вызвать эту функцию еще раз:
np.random.shuffle(a) # array([7, 2, 1, 5, 8, 6, 4, 3, 9, 0])
то значения еще
раз перетасуются. Но, работает она только с первой осью axis0. Например,
если взять двумерный массив:
a = np.arange(1, 10).reshape(3, 3)
и вызвать эту
функцию:
то в массиве aбудут
переставлены только строки:
array([[1,
2, 3],
[7, 8, 9],
[4, 5, 6]])
Вторая функция
возвращает случайную последовательность чисел, генерируя последовательность «на
лету»:
np.random.permutation(10) # array([8, 2, 7, 1, 0, 5, 3, 9, 4, 6])
Функции математической статистики
Последняя группа
общематематических функций, которую мы рассмотрим на этом занятии, отвечает за
вычисления статистических характеристик случайных величин. Основные из них,
следующие:
Название
|
Описание
|
np.median(x)
|
Вычисление
медианы величин x
|
np.var(x)
|
Дисперсия
величин x
|
np.std(x)
|
Среднеквадратическое
отклонение величин x
|
np.corrcoef(x)
|
Линейный
коэффициент корреляции Пирсона
|
np.correlate(x)
|
Вычисление
кросс-корреляции
|
np.cov(x)
|
Вычисление
ковариационной матрицы
|
Рассмотрим
работу этих функций. Предположим, имеются следующие векторы:
x = np.array([1, 4, 3, 7, 10, 8, 14, 21, 20, 23])
y = np.array([4, 1, 6, 9, 13, 11, 16, 19, 15, 22])
Эти числа будем
воспринимать как реализации случайных величин X и Y. Тогда, для
вычисления медианы СВX, можно воспользоваться функцией:
Для расчета
дисперсии и СКО, функциями:
np.var(x) # дисперсия СВX на основе реализации x
np.std(y) # СКО СВY на основе реализации y
Далее, чтобы
рассчитать коэффициент корреляции Пирсона, объединим массивыx и y построчно:
XY = np.vstack([x, y]) # матрица 2x10
и выполним
функцию:
Результатом
будет матрица 2x2:
array([[1.
, 0.93158099],
[0.93158099, 1. ]])
Как ее следует
интерпретировать? В действительности, это автоковариационная матрица вектора СВ[X, Y]:
(В этой формуле
полагается, что СВX и Y центрированы, то есть имеют нулевое
математическое ожидание).
Если нужно
вычислить не нормированное МО, то есть, автоковариационную матрицу, то следует
воспользоваться функцией:
np.cov(XY) # ковариационная матрица размерностью 2x2
Наконец, для
вычисления взаимной корреляции между двумя векторамиx и y, используется
функция:
np.correlate(x, y) # array([1736])
Более детальную
информацию по этим статистическим функциям можно найти в официальной
документации пакета NumPy:
https://numpy.org/doc/stable/
Конечно, мы
рассмотрели далеко не все математические функции NumPy. На следующем
занятии продолжим эту тему и поговорим об умножении векторов и матриц, линейной
алгебре и множествах.
|