- Вступление
- Преимущества NumPy
- NumPy Операции
- Создание массива NumPy
- Изменение формы массива NumPy
- Поиск максимальных / минимальных значений
- Индексирование массивов в NumPy
- Арифметические операции с массивами NumPy
- Операции линейной алгебры с массивами NumPy
- Заключение
Вступление
Библиотека NumPy - это популярная библиотека Python, используемая для приложений научных вычислений, и является аббревиатурой от «Numerical Python». Операции NumPy делятся на три основные категории: преобразование Фурье и манипуляции с формой, математические и логические операции, а также линейная алгебра и генерация случайных чисел. Чтобы сделать это как можно быстрее, NumPy написан на C и Python.
В этой статье мы дадим краткое введение в стек NumPy и увидим, как библиотеку NumPy можно использовать для выполнения множества математических задач.
Преимущества NumPy
NumPy имеет несколько преимуществ перед использованием основных математических функций Python, некоторые из которых описаны здесь:
- NumPy чрезвычайно быстр по сравнению с ядром Python благодаря интенсивному использованию расширений C.
- Многие продвинутые библиотеки Python, такие как Scikit-Learn, Scipy и Keras, широко используют библиотеку NumPy. Поэтому, если вы планируете продолжить карьеру в области науки о данных или машинного обучения, NumPy - очень хороший инструмент для освоения.
- NumPy поставляется с множеством встроенных функций, которые в ядре Python потребуют значительного количества настраиваемого кода.
Что касается последнего пункта, взгляните на следующий скрипт:
x = [2, 3, 4, 5, 6]
y = [a + 2 for a in x]
Здесь, чтобы добавить 2 к каждому элементу в списке x
, мы должны
пройти весь список и добавить 2 к каждому элементу индивидуально. Теперь
посмотрим, как мы можем выполнить ту же задачу с библиотекой NumPy:
import numpy as np
nums = np.array([2, 3, 4, 5, 6])
nums2 = nums + 2
Вы можете увидеть, как легко добавить скалярное значение к каждому элементу в списке через NumPy. Он не только читается, но и быстрее по сравнению с предыдущим кодом.
Это лишь верхушка айсберга, на самом деле библиотека NumPy способна выполнять гораздо более сложные операции в мгновение ока. Давайте рассмотрим некоторые из этих операций.
NumPy Операции
Прежде чем мы сможем выполнять какие-либо операции NumPy, нам необходимо установить пакет NumPy. Чтобы установить пакет NumPy, вы можете использовать установщик pip. Для установки выполните следующую команду:
$ pip install numpy
В противном случае, если вы используете Python через дистрибутив Anaconda, вы можете вместо этого выполнить следующую команду:
$ conda install numpy
Теперь, когда NumPy установлен, давайте посмотрим на некоторые из наиболее распространенных операций библиотеки.
Создание массива NumPy
Массивы NumPy являются строительными блоками большинства операций NumPy. Массивы NumPy можно разделить на два типа: одномерные массивы и двумерные массивы.
Есть несколько способов создать массив NumPy. В этом разделе мы обсудим некоторые из них.
Метод массива
Чтобы создать одномерный массив NumPy, мы можем просто передать список
Python в метод array
Посмотрите следующий сценарий в качестве примера:
import numpy as np
x = [2, 3, 4, 5, 6]
nums = np.array([2, 3, 4, 5, 6])
type(nums)
В приведенном выше скрипте мы сначала импортировали библиотеку NumPy как
np
и создали список x
. Затем мы передали этот список array
библиотеки NumPy. Наконец, мы распечатали тип массива, что привело к
следующему выводу:
numpy.ndarray
Если бы вы распечатали nums
на экране, вы бы увидели, что он
отображается следующим образом:
array([2, 3, 4, 5, 6])
Чтобы создать двумерный массив, вы можете передать список списков
array
как показано ниже:
nums = np.array([[2,4,6], [8,10,12], [14,16,18]])
Результатом приведенного выше сценария является матрица, в которой каждый внутренний список внешнего списка становится строкой. Количество столбцов равно количеству элементов в каждом внутреннем списке. Выходная матрица будет выглядеть так:
array([[ 2, 4, 6],
[ 8, 10, 12],
[14, 16, 18]])
Метод аранжа
Другой часто используемый метод создания массива NumPy - это метод
arange
Этот метод принимает начальный индекс массива, конечный индекс
и размер шага (который является необязательным). Взгляните на следующий
пример:
nums = np.arange(2, 7)
Достаточно просто, правда? Приведенный выше сценарий вернет массив NumPy
размером 5 с элементами 2, 3, 4, 5 и 6. Помните, что arange
возвращает
массив, который начинается с начального индекса и заканчивается на один
индекс меньше, чем конечный индекс. Вывод этого кода выглядит так:
array([2, 3, 4, 5, 6])
Теперь давайте добавим к нашему массиву размер шага 2 и посмотрим, что произойдет:
nums = np.arange(2, 7, 2)
Теперь результат выглядит так:
array([2, 4, 6])
Вы можете видеть, что массив начинается с 2, за ним следует размер шага 2 и заканчивается на 6, что на единицу меньше конечного индекса.
Метод нулей
Помимо создания настраиваемых массивов с вашими предварительно
заполненными данными, вы также можете создавать массивы NumPy с более
простым набором данных. Например, вы можете использовать zeros
для
создания массива всех нулей, как показано ниже:
zeros = np.zeros(5)
Приведенный выше скрипт вернет одномерный массив из 5 нулей.
Распечатайте zeros
и вы должны увидеть следующее:
array([0., 0., 0., 0., 0.])
Точно так же, чтобы создать двумерный массив, вы можете передать
количество строк и столбцов zeros
, как показано ниже:
zeros = np.zeros((5, 4))
Приведенный выше скрипт вернет двумерный массив из 5 строк и 4 столбцов:
array([[0., 0., 0., 0.],
[0., 0., 0., 0.],
[0., 0., 0., 0.],
[0., 0., 0., 0.],
[0., 0., 0., 0.]])
Единственный метод
Точно так же вы можете создавать одномерные и двухмерные массивы всех
единиц, используя ones
следующим образом:
ones = np.ones(5)
array([1., 1., 1., 1., 1.])
И снова для двумерного массива попробуйте следующий код:
ones = np.ones((5, 4))
Теперь, если вы распечатаете ones
на экране, вы должны увидеть
следующий двумерный массив:
[[1. 1. 1. 1.]
[1. 1. 1. 1.]
[1. 1. 1. 1.]
[1. 1. 1. 1.]
[1. 1. 1. 1.]]
Метод линспейса
Еще один очень полезный метод создания массивов NumPy - это метод
linspace
Этот метод принимает три аргумента: начальный индекс,
конечный индекс и количество чисел с линейным интервалом, которое вы
хотите между указанным диапазоном. Например, если первый индекс равен 1,
последний индекс равен 10 и вам нужно 10 элементов с равным интервалом в
этом диапазоне, вы можете использовать linspace
следующим образом:
lin = np.linspace(1, 10, 10)
Вывод вернет целые числа от 1 до 10:
array([1., 2., 3., 4., 5., 6., 7., 8., 9., 10.])
Теперь давайте попробуем создать массив из 20 линейно расположенных элементов от 1 до 10. Выполните следующий скрипт:
lin = np.linspace(1, 10, 20)
В результате получится следующий массив:
array([ 1. , 1.47368421, 1.94736842, 2.42105263, 2.89473684,
3.36842105, 3.84210526, 4.31578947, 4.78947368, 5.26315789,
5.73684211, 6.21052632, 6.68421053, 7.15789474, 7.63157895,
8.10526316, 8.57894737, 9.05263158, 9.52631579, 10. ])
Обратите внимание, что результат может выглядеть как матрица, но на самом деле это одномерный массив. Из-за проблемы с интервалом элементы отображались в несколько строк.
Метод глаза
Метод eye
можно использовать для создания единичной
матрицы , которая может
быть очень полезна для выполнения множества операций в линейной алгебре.
Единичная матрица - это матрица с нулями в строках и столбцах, кроме
диагонали. Значения по диагонали - все единицы. Создадим единичную
матрицу 4x4 с помощью метода eye
idn = np.eye(4)
Результирующая матрица выглядит так:
array([[1., 0., 0., 0.],
[0., 1., 0., 0.],
[0., 0., 1., 0.],
[0., 0., 0., 1.]])
Случайный метод
Часто вам нужно создавать массивы со случайными числами. Для этого вы
можете использовать функцию rand
модуля random
Вот простой пример
функции rand
random = np.random.rand(2, 3)
Приведенный выше сценарий возвращает матрицу из 2 строк и 3 столбцов. Матрица содержит равномерное распределение чисел от 0 до 1:
array([[0.26818562, 0.65506793, 0.50035001],
[0.527117 , 0.445688 , 0.99661 ]])
Точно так же, чтобы создать матрицу случайных чисел с распределением
Гаусса (или
«нормальным» распределением), вы можете вместо этого использовать
randn
как показано ниже:
random = np.random.randn(2, 3)
Наконец, для создания массива случайных целых чисел в randint
существует метод randint. Метод randint
принимает нижнюю границу,
верхнюю границу и количество возвращаемых целых чисел. Например, если вы
хотите создать массив из 5 случайных целых чисел от 50 до 100, вы можете
использовать этот метод следующим образом:
random = np.random.randint(50, 100, 5)
В нашем случае результат выглядел так:
array([54, 59, 84, 62, 74])
Важно отметить, что эти числа генерируются случайным образом каждый раз, когда вы вызываете метод, поэтому вы увидите другие числа, чем в нашем примере.
Мы видели разные способы создания массивов Python. Давайте теперь рассмотрим некоторые другие функции массива.
Изменение формы массива NumPy
Используя NumPy, вы можете преобразовать одномерный массив в двумерный
массив, используя метод reshape
Давайте сначала создадим массив из 16 элементов, используя функцию
arange
Выполните следующий код:
nums = np.arange(1, 17)
nums
представляет собой одномерный массив из 16 элементов в диапазоне
от 1 до 16:
array([ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16])
Нет, давайте преобразуем его в двумерный массив из 4 строк и 4 столбцов:
nums2 = nums.reshape(4, 4)
Теперь массив выглядит так:
array([[ 1, 2, 3, 4],
[ 5, 6, 7, 8],
[ 9, 10, 11, 12],
[13, 14, 15, 16]])
Уместно упомянуть, что вы не можете изменить форму массива, если количество элементов в одномерном массиве не равно произведению строк и столбцов измененного массива. Например, если у вас 45 элементов в одномерном массиве, вы не можете преобразовать его в матрицу из 5 строк и 10 столбцов, поскольку матрица 5x10 имеет 50 элементов, а исходная - только 45.
Поиск максимальных / минимальных значений
Вы можете использовать функции min
/ max
чтобы легко найти значение
наименьшего и наибольшего числа в вашем массиве. В нашем примере давайте
сначала создадим массив из 5 случайных целых чисел:
random = np.random.randint(1, 100, 5)
print(random)
Наш массив случайных целых чисел выглядит так:
[51 40 84 38 1]
Помните, что эти числа генерируются случайным образом, поэтому у вас,
скорее всего, будет другой набор чисел. Давайте воспользуемся min
и
max
чтобы найти минимальное и максимальное значения из только что
созданного массива. Для этого выполните следующий код, чтобы найти
минимальное значение:
xmin = random.min()
print(xmin)
На выходе будет напечатано «1».
Точно так же для максимального значения выполните следующий код:
xmax = random.max()
print(xmax)
Приведенный выше сценарий вернет в качестве вывода "84".
Вы также можете найти индекс максимального и минимального значений,
используя функции argmax()
и argmin()
. Взгляните на следующий
сценарий:
print(random.argmax())
Приведенный выше сценарий напечатает «2», поскольку 84 - это наибольшее число в списке, и оно находится во второй позиции массива.
Точно так же argmin()
вернет «4», потому что 1 - наименьшее число и
находится в 4-й позиции.
Индексирование массивов в NumPy
Чтобы эффективно использовать массивы NumPy, очень важно понимать способ индексации массивов, который я расскажу в следующих нескольких разделах.
Индексирование с помощью одномерных массивов
Создадим простой массив из 15 чисел:
nums = np.arange(1, 16)
Вы можете получить любой элемент, передав номер индекса. Как и списки Python, массивы NumPy имеют нулевой индекс. Например, чтобы найти элемент во втором индексе (3-й позиции) массива, вы можете использовать следующий синтаксис:
print(nums[2])
У нас есть цифра 3 во втором индексе, поэтому она будет напечатана на экране.
Вы также можете распечатать диапазон чисел с помощью индексации. Чтобы получить диапазон, вам необходимо передать начальный индекс и индекс на единицу меньше конечного, разделенные двоеточием, внутри квадратных скобок, следующих за именем массива. Например, чтобы получить элементы с первого по седьмой индекс, вы можете использовать следующий синтаксис:
print(nums[1:8])
Приведенный выше скрипт напечатает целые числа от 2 до 8:
[2 3 4 5 6 7 8]
Здесь, в nums
, у нас есть 2 в индексе 1 и 8 в индексе семь.
Вы также можете нарезать массив и назначить элементы нарезанного массива новому массиву:
nums2 = nums[0:8]
print(nums2)
В приведенном выше сценарии мы разрезали nums
, извлекая его первые 8
элементов. Результирующие элементы присваиваются массиву nums2
Затем
мы nums2
массив nums2 на консоль. На выходе получается новый массив из
первых 8 чисел:
[1 2 3 4 5 6 7 8]
Индексирование с помощью двумерных массивов
Индексирование двумерного массива NumPy очень похоже на индексирование матрицы. Давайте сначала создадим двумерный массив NumPy 3x3. Для этого запустите следующий код:
nums2d = np.array(([1,2,3],[4,5,6],[7,8,9]))
Теперь распечатаем:
print(nums2d)
[[1 2 3]
[4 5 6]
[7 8 9]]
Как и одномерные массивы, массивы NumPy с двумя измерениями также следуют за индексом, отсчитываемым от нуля, то есть, чтобы получить доступ к элементам в первой строке, вы должны указать 0 в качестве индекса строки. Аналогично для доступа к элементам в первом столбце вам также необходимо указать 0 для индекса столбца.
nums2d
элемент из массива nums2d, расположенный в первой строке и
первом столбце:
print(nums2d[0, 0])
На выходе вы увидите «1». Точно так же мы можем получить элемент в третьей строке и третьем столбце следующим образом:
print(nums2d[2, 2])
На выходе вы увидите цифру «9».
Помимо извлечения одного элемента, вы можете извлечь всю строку, передав
в квадратные скобки только индекс строки. Например, следующий скрипт
возвращает первую строку из массива nums2d
print(nums2d[0])
На выходе получается одномерный массив:
[1 2 3]
Аналогично, чтобы получить только первый столбец, вы можете использовать следующий синтаксис:
print(nums2d[:,0])
Результатом снова является массив, но это комбинация первых элементов каждого массива двумерного массива:
[1 4 7]
Наконец, чтобы получить элементы из первых двух строк и первых двух столбцов, можно использовать следующий синтаксис:
print(nums2d[:2,:2])
Приведенный выше сценарий возвращает следующий результат:
[[1 2]
[4 5]]
Арифметические операции с массивами NumPy
Для примеров в этом разделе мы будем использовать nums
который мы
создали в последнем разделе.
Давайте сначала сложим два массива:
nums3 = nums + nums
Вы можете добавить два массива с одинаковыми размерами. Например, nums
содержит 15 элементов, поэтому мы можем добавить его к себе. Будут
добавлены элементы с соответствующими индексами. Теперь, если вы
распечатаете nums3
, результат будет выглядеть так:
[ 2 4 6 8 10 12 14 16 18 20 22 24 26 28 30]
Как видите, каждая позиция - это сумма двух элементов в этой позиции в исходных массивах.
Если вы добавите массив со скалярным значением, значение будет добавлено
к каждому элементу в массиве. Добавим 10 в nums
и выведем полученный
массив на консоль. Вот как бы вы это сделали:
nums3 = nums + 10
print(nums3)
И результирующий nums3
становится:
[11 12 13 14 15 16 17 18 19 20 21 22 23 24 25]
Таким же образом можно выполнять вычитание, сложение, умножение и деление.
Помимо простой арифметики, вы можете выполнять более сложные функции с массивами Numpy, например, журнал, квадратный корень, экспоненциальный и т. Д.
Функция журнала
Следующий код просто возвращает массив с журналом всех элементов входного массива:
nums3 = np.log(nums)
print(nums3)
Результат выглядит так:
[0. 0.69314718 1.09861229 1.38629436 1.60943791 1.79175947
1.94591015 2.07944154 2.19722458 2.30258509 2.39789527 2.48490665
2.56494936 2.63905733 2.7080502 ]
Функция exp
Следующий скрипт возвращает массив с показателями всех элементов входного массива:
nums3 = np.exp(nums)
print(nums3)
[2.71828183e+00 7.38905610e+00 2.00855369e+01 5.45981500e+01
1.48413159e+02 4.03428793e+02 1.09663316e+03 2.98095799e+03
8.10308393e+03 2.20264658e+04 5.98741417e+04 1.62754791e+05
4.42413392e+05 1.20260428e+06 3.26901737e+06]
Функция sqrt
Следующий скрипт возвращает массив с квадратными корнями всех элементов входного массива:
nums3 = np.sqrt(nums)
print(nums3)
[1. 1.41421356 1.73205081 2. 2.23606798 2.44948974
2.64575131 2.82842712 3. 3.16227766 3.31662479 3.46410162
3.60555128 3.74165739 3.87298335]
Функция греха
Следующий скрипт возвращает массив с синусами всех элементов входного массива:
nums3 = np.sin(nums)
print(nums3)
[ 0.84147098 0.90929743 0.14112001 -0.7568025 -0.95892427 -0.2794155
0.6569866 0.98935825 0.41211849 -0.54402111 -0.99999021 -0.53657292
0.42016704 0.99060736 0.65028784]
Операции линейной алгебры с массивами NumPy
Одним из самых больших преимуществ массивов NumPy является их способность выполнять операции линейной алгебры, такие как векторное скалярное произведение и матричное скалярное произведение, намного быстрее, чем вы можете со списками Python по умолчанию.
Нахождение векторного точечного произведения
Вычисление скалярного произведения векторов для двух векторов может быть вычислено путем умножения соответствующих элементов двух векторов и последующего сложения результатов из произведений.
Создадим два вектора и попробуем найти их скалярный продукт вручную. Вектор в NumPy - это просто одномерный массив. Выполните следующий скрипт, чтобы создать наши векторы:
x = np.array([2,4])
y = np.array([1,3])
Скалярное произведение двух вышеуказанных векторов равно
(2 x 1) + (4 x 3) = 14
.
Давайте найдем точечный продукт без использования библиотеки NumPy. Для этого выполните следующий сценарий:
dot_product = 0
for a,b in zip(x,y):
dot_product += a * b
print(dot_product)
В приведенном выше скрипте мы просто перебирали соответствующие элементы
в x
и y
, умножали их и добавляли к предыдущей сумме. Если вы
запустите приведенный выше сценарий, вы увидите «14», напечатанное на
консоли.
Теперь давайте посмотрим, как мы можем найти точечный продукт с помощью библиотеки NumPy. Взгляните на следующий сценарий:
a = x * y
print(a.sum())
Мы знаем, что если мы умножим два массива NumPy, соответствующие
элементы из обоих массивов умножатся на основе их индекса. В приведенном
выше сценарии мы просто перемножили векторы x
и y
Затем мы вызываем
sum
для результирующего массива, который суммирует все элементы
массива. Вышеупомянутый сценарий также вернет на выходе «14».
Вышеупомянутый метод прост, однако библиотека NumPy упрощает поиск
точечного произведения с помощью dot
метода, как показано здесь:
print(x.dot(y))
Для очень больших массивов вы также должны заметить улучшение скорости по сравнению с нашей версией только для Python, благодаря использованию NumPy кода C для реализации многих своих основных функций и структур данных.
Умножение матриц
Подобно скалярному произведению двух векторов, вы также можете умножить две матрицы. В NumPy матрица - это не что иное, как двумерный массив. Чтобы перемножить две матрицы, внутренние размеры матриц должны совпадать, а это означает, что количество столбцов матрицы слева должно быть равно количеству строк матрицы справа от произведения. Например, если матрица X имеет размеры [3,4], а другая матрица Y имеет размеры [4,2], то матрицы X и Y могут быть перемножены. Результирующая матрица будет иметь размеры [3,2], которые являются размером внешних измерений.
Для умножения двух матриц dot
функцию, как показано ниже:
X = np.array(([1,2,3], [4,5,6]))
Y = np.array(([1,2], [4,5], [7,8]))
Z = np.dot(X, Y)
print(Z)
В приведенном выше скрипте мы создали матрицу 3x2 с именем X
и матрицу
2x3 с именем Y
Затем мы находим скалярное произведение двух матриц и
присваиваем полученную матрицу переменной Z
Наконец, мы выводим
полученную матрицу на консоль. На выходе вы должны увидеть матрицу 2x2,
как показано ниже:
[[30 36]
[66 81]]
Вы также можете поэлементно перемножить две матрицы. Для этого размеры
двух матриц должны совпадать, как когда мы складывали массивы вместе.
Функция multiply
используется для поэлементного умножения.
Попробуем поэлементно перемножить матрицы X
и Y
Z = np.multiply(X, Y)
Следующая ошибка произойдет, когда вы запустите приведенный выше код:
ValueError: operands could not be broadcast together with shapes (2,3) (3,2)
Ошибка возникает из-за несовпадения размеров матриц X
и Y
Теперь
давайте попробуем умножить X
на себя с помощью функции multiply
Z = np.multiply(X, X)
Теперь, если вы распечатаете Z
, вы должны увидеть следующий
результат:
[[ 1 4 9]
[16 25 36]]
X
успешно умножалась сама с собой, потому что размеры умноженных
матриц совпадали.
Нахождение обратной матрицы
Еще одна очень полезная операция с матрицей - это поиск обратной
матрицы. Библиотека NumPy содержит ìnv
функцию в linalg
модуле.
В нашем примере давайте найдем обратную матрицу 2x2. Взгляните на следующий код:
Y = np.array(([1,2], [3,4]))
Z = np.linalg.inv(Y)
print(Z)
Вывод приведенного выше кода выглядит следующим образом:
[[-2. 1. ]
[ 1.5 -0.5]]
Теперь, чтобы проверить, правильно ли было вычислено обратное, мы можем взять скалярное произведение матрицы на обратное, что должно дать единичную матрицу.
W = Y.dot(Z)
print(W)
[[1.00000000e+00 1.11022302e-16]
[0.00000000e+00 1.00000000e+00]]
И результат оказался таким, как мы и ожидали. Единицы по диагонали и нули (или очень близкие к нулю) в других местах.
Нахождение определителя матрицы
Определитель матрицы можно
вычислить с помощью det
, который показан здесь:
X = np.array(([1,2,3], [4,5,6], [7,8,9]))
Z = np.linalg.det(X)
print(Z)
В приведенном выше скрипте мы создали матрицу 3x3 и нашли ее
определитель с помощью метода det
В выводе вы должны увидеть
«6.66133814775094e-16».
Нахождение следа матрицы
След матрицы - это сумма всех элементов диагонали матрицы. Библиотека
NumPy содержит trace
которую можно использовать для поиска трассировки
матрицы. Взгляните на следующий пример:
X = np.array(([1,2,3], [4,5,6], [7,8,9]))
Z = np.trace(X)
print(Z)
На выходе вы должны увидеть «15», поскольку сумма диагональных элементов
матрицы X
равна 1 + 5 + 9 = 15
.
Заключение
Библиотека Pythons NumPy - одна из самых популярных библиотек для числовых вычислений. В этой статье мы подробно изучили библиотеку NumPy с помощью нескольких примеров. Мы также показали, как выполнять различные операции линейной алгебры через библиотеку NumPy, которая обычно используется во многих приложениях для обработки данных.
Хотя мы рассмотрели довольно много основных функций NumPy, нам еще предстоит многому научиться. Если вы хотите узнать больше, я предлагаю вам попробовать такой курс, как Data Science в Python, Pandas, Scikit-learn, Numpy, Matplotlib{.udemy-link} , который охватывает NumPy, Pandas, Scikit-learn и Matplotlib гораздо глубже, чем то, что мы смогли прикрыть здесь.
Я предлагаю вам попрактиковаться в примерах из этой статьи. Если вы планируете начать карьеру в качестве специалиста по данным, библиотека NumPy определенно является одним из инструментов, которые вам необходимо изучить, чтобы стать успешным и продуктивным специалистом в этой области.