Занятие 3
Лабораторная работа 3¶
NumPy(сокращенно от Numerical Python)— библиотека с открытым исходным кодом для языка программирования Python.
- поддержмвает многомерные массивы (включая матрицы)
- поддерживает высокоуровневые математические функции, предназначенные для работы с многомерными массивами.
NumPy обеспечивает как гибкость Python, так и скорость хорошо оптимизированного скомпилированного кода на C.
Если у вас ещё не установлен Numpy это можно сделать командой: pip install numpy
Туторила NumPy: https://numpy.org
0. Массивы в Numpy¶
- Массив в NumPy это таблица элементов одного типа, пронумерованная кортежем положительных целых чисел.
- В NumPy измерения называются осями. Количество осей является рангом.
- Класс массива NumPy называется ndarray.
Обратите внимание, что массив в Numpy содержит элементы одного типа, в отличие от списка!
import numpy as np # импортируем библиотеку и заменим её ключевым словом np(для удобства)
1. Создание массива¶
Есть несколько способов создать массив NumPy. Рассмотрим их подробнее:
1. Создание из списков или кортежей¶
Вы можете создать массив, передав списки или кортежи в функцию np.array()
:
# Создание одномерного массива
array_1d = np.array([1, 2, 3, 4, 5])
print(array_1d)
# Создание двумерного массива
array_2d = np.array([[1, 2, 3], [4, 5, 6]])
print(array_2d)
2. Создание пустых, нулевых и единичных массивов¶
Для создания массивов, заполненных нулями, единицами или пустых (неинициализированных), можно использовать следующие функции:
np.zeros(shape)
: создает массив, заполненный нулями.np.ones(shape)
: создает массив, заполненный единицами.np.empty(shape)
: создает пустой массив (значения не инициализированы).
# Массив нулей
zeros_array = np.zeros((2, 3))
print(zeros_array)
# Массив единиц
ones_array = np.ones((3, 2))
print(ones_array)
# Пустой массив
empty_array = np.empty((2, 2))
print(empty_array)
3. Создание массивов с равномерным распределением¶
Для создания массивов с равномерным распределением чисел можно использовать функции np.arange()
и np.linspace()
:
np.arange(start, stop, step)
: создает массив чисел от start до stop с заданным шагом.np.linspace(start, stop, num)
: создает массив из num равномерно распределенных точек между start и stop.
# Массив с использованием np.arange
arange_array = np.arange(0, 10, 2) # от 0 до 10 с шагом 2
print(arange_array)
# Массив с использованием np.linspace
linspace_array = np.linspace(0, 1, 5) # 5 равномерных точек от 0 до 1
print(linspace_array)
4. Создание массивов с нормальным распределением¶
Массивы, заполненные случайными числами, можно создавать с помощью функции np.random
:
# Массив с нормально распределёнными числами
random_array = np.random.normal(loc=0.0, scale=1.0, size=(2, 3)) # 2x3 массив
print(random_array)
5. Создание идентичного массива¶
Для создания единичной матрицы (матрицы, в которой все элементы на главной диагонали равны 1, а остальные равны 0):
identity_matrix = np.eye(3) # Создание 3x3 единичной матрицы
print(identity_matrix)
6. Повторение и объединение массивов¶
Вы можете использовать функции np.tile()
и np.concatenate()
для повторения или объединения массивов:
np.tile(array, reps)
: повторяет массив reps раз.np.concatenate((array1, array2), axis)
: объединяет два массива по указанному оси.
2. Идексация массивов¶
1. Одномерная индексация¶
Для одномерных массивов вы можете использовать обычные квадратные скобки [] и указывать индекс элемента. Индексы начинаются с 0.
# Создание одномерного массива
array_1d = np.array([10, 20, 30, 40, 50])
# Индексация
print(array_1d[0]) # 10 (первый элемент)
print(array_1d[2]) # 30 (третий элемент)
2. Индексация двумерных массивов¶
Для двумерных массивов индексы указываются как кортежи, где первый индекс – это номер строки, а второй – номер столбца.
# Создание двумерного массива
array_2d = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
# Индексация
print(array_2d[0, 1]) # 2 (первая строка, второй столбец)
print(array_2d[2, 0]) # 7 (третья строка, первый столбец)
3. Срезы¶
Срезы в NumPy работают аналогично обычным спискам Python. Вы можете указать начальный и конечный индексы, и NumPy извлечет элементы в заданном диапазоне.
# Срез для одномерного массива
print(array_1d[1:4]) # [20 30 40]
# Срез для двумерного массива
print(array_2d[0:2, 1:3]) # [[2 3]
# [5 6]]
4. Индексация с помощью массивов¶
Вы можете использовать логическую маску или массив индексов для извлечения данных.
# Индексация с помощью логической маски
mask = array_1d > 30
print(array_1d[mask]) # [40 50]
5. Изменение элементов¶
Вы можете изменять значения элементов массива, используя индексы.
array_1d[0] = 100
print(array_1d) # [100 20 30 40 50]
3. Операции над массивами¶
1 Математические операции¶
# создадим два массива
a = np.array([(1, 2, 3), (4, 5, 6), (7, 8, 9)])
b = np.array([(19, 20, 21), (22, 23, 24), (25, 26, 27)])
Мы можем складывать, умножать, делить, считать остаток и т.д поэлементно.
# сумма
print(a + b)
# разность
print(a - b)
# умножение
print(a * b)
# остаток от деления
print(b % a)
# Также, в numpy есть библиотека стандартных мат функций, которые можно применить к каждому элементу массива.
a = np.array([(1, 2, 3), (4, 5, 6), (7, 8, 9)])
np.sqrt(a)
2 Базовые операции с массивыми¶
a = np.array([(1, 2, 3, 4, 5, 6, 7, 8, 9)])
# сумма элементов
print(a.sum())
# произведение элементов
print(a.prod())
# макс и мин элемент
print(a.max())
print(a.min())
# среднее значение
print(a.mean())
# дисперсия
print(a.var())
P.S NumPy - мощный интсрумент, который содержит в себе много функций и методов.
Обращайтесь к туториалу: https://numpy.org/devdocs/user/quickstart.html
И не бойтесь гуглить!
Задача 1¶
Создайте две numpy матрицы, содержащие температуры в Кельвинах и Фаренгейтах на основе матрицы температур в Цельсиях.
a = np.array([(14, 23, 31, 14, 55, 36, 87, 118, 91)]) # матрица температур(в Цельсиях)
Задача 2¶
Создайте матрицу с 0 внутри и 1 на границах.
3 Умножения матриц¶
a = np.array([(1, 2, 3), (4, 5, 6), (7, 8, 9)])
a = np.array([(1), (4), (7)])
# можем так
print(a @ b)
# а можем так
print(a.dot(b))
A = np.array([[1.0, 2.0, 3.0],
[4.0, 5.0, 6.0]])
B = np.array([[11.0, 12.0],
[13.0, 14.0],
[15.0, 16.0]])
Задача 4¶
Мы можем расчитать норму вектора: np.linalg.norm([1.0, 2.0, 3.0]).
Найдите косинус угла между векторами:
- используя np.linalg.norm
- не используя
a = np.array([1.0, 2.0, 3.0])
b = np.array([4.0, 5.0, 6.0])
4. Линейнай алгебра в NumPy¶
1 Решение систем линейных уравнений¶
Библиотеку numpy удобно использовать для решения систем линейных уравнений. Если система уравнений $Ax = y$ имеет решение, и при этом только одно, то оно выражается как $x = A^{-1}y$ . Для обращения матрицы используется функция np.linalg.inv. Рассмотрим систему уравнений: $$ \left\{ \begin{array}{c} 2x + z = 1 \\ x - z = 4 \\ \end{array} \right. $$
A = np.array([[2.0, 1.0],
[1.0, -1.0]])
y = np.array([1.0, 4.0])
# решение будет
print(np.linalg.inv(A) @ y)
Задача 5¶
Решите следующую систему:
2 Ещё немного линейной алгебры¶
B = np.array([[11.0, 12.0],
[13.0, 14.0]])
5. Математика многочленов¶
1 np.poly¶
# np.poly - передаём список корней, получаем коэффициенты уравнения, которое имеет данные корни:
np.poly([-1, 1, 2])
Получили уравнение:
$x^3 -2x^2 -x + 2 =0$
2 roots¶
# np.roots - передаём список коэффициентов уравнения, возвращаем корни.
np.roots([1, -5, 6])
Мы решили уравнение: $x^2 - 5x + 6 = 0$
Задача 7¶
Напишите функцию решающую квадратное уравнение и принимающую на вход коэффициенты этого уравнения.
6. Продвинутые методы numpy¶
1. Сортировка и поиск¶
np.sort()
: Функция для сортировки элементов массива.np.argsort()
: Возвращает индексы отсортированных значений.np.searchsorted()
: Находит индексы, в которые надо вставить элементы для сохранения сортировки.
array_unsorted = np.array([3, 1, 2, 5, 4])
sorted_array = np.sort(array_unsorted)
print(sorted_array) # [1 2 3 4 5]
indices = np.argsort(array_unsorted)
print(indices) # [1 2 0 4 3] (индексы отсортированных значений)
2. Функции агрегации¶
Сборка и разделение массивов
- Сборка: функции
np.concatenate()
,np.vstack()
,np.hstack()
позволяют объединять массивы вдоль различных осей. - Разделение: функции
np.split()
,np.hsplit()
,np.vsplit()
позволяют делить массивы на подмассивы.
array1 = np.array([1, 2, 3])
array2 = np.array([4, 5, 6])
combined = np.concatenate((array1, array2)) # Сборка
print(combined) # [1 2 3 4 5 6]
splitted = np.split(combined, 2) # Разделение на 2 подмассивы
print(splitted) # [array([1, 2, 3]), array([4, 5, 6])]
3. Работа с пропусками¶
NumPy предоставляет функции для обработки данных с пропусками.
np.nanmean()
: Вычисляет среднее значение, игнорируя NaN.np.isnan()
: Проверяет, являются ли элементы массива NaN.
array_with_nan = np.array([1, 2, np.nan, 4])
mean_value = np.nanmean(array_with_nan)
print(mean_value) # 2.3333333333333335 (игнорируя NaN)
Задача 9¶
Создайте два массива: один — из первых 5 четных чисел, а другой — из первых 5 нечетных. Объедините их в один массив и затем разделите на два отдельных массива.
Задача 10¶
Создайте двумерный массив 4x4 с произвольными числами. Найдите сумму всех элементов, среднее по строкам и стандартное отклонение по столбцам.
Задача 11¶
Создайте массив из 15 случайных целых чисел от 1 до 100. Отсортируйте массив и на его основе найдите индексы отсортированных значений. Затем найдите индекс, по которому нужно вставить число 50, чтобы сохранить порядок сортировки.
Задача 12¶
Создайте массив с 10 элементами, в котором будут значения от 1 до 10, но замените некоторые значения на NaN. Используя функции NumPy, найдите среднее значение всех элементов, игнорируя NaN.
Задача 13¶
Дано 4 точки у каждой из которых есть координата x и y. Значения x и y каждой точки представлены в матрице A.
Преобразуйте их в полярные координаты.
Задача 14¶
Найдите наиболее частое значение в массиве.
Задача 15¶
Создайте класс Matrix, добавьте в него методы сложения, умножения, транспонирования, возведения в степень для матриц.
Задача 16¶
Пусть дано n, матрица A. Напишите функцию, вычисляющую ряд: $A + A^2 + ... A^n$.