Введение в анализ данных¶
Задачи для самостоятельного решения¶
- Данные задачи предназначены для самостоятельного прорешивания задач по желанию студента с целью освоения основой функциональности библиотек
numpy
,pandas
,matplotlib
,seaborn
. - Решения задач сдавать не нужно, они не проверяются и не учитываются в итоговой оценке.
- При возникновении проблем при решении задач обратитесь к материалам курса по Питону или спросите совета у ИИ-инструментов.
- При необходимости попросите дополнительные задачи у ИИ-инструментов.
- Также рекомендуем прорешать два упражнения на numpy в системе Яндекс.Контест.
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
import pandas as pd
sns.set_palette("Set2")
Библиотека numpy
¶
Используйте библиотеку numpy
для задач в этом блоке
Задача 1¶
- Создайте одномерный массив размером 10, составленный из чисел от 1 до 10
- Преобразуйте его в двумерный массив размером 2х5
Задача 2¶
- Создайте 2 массива одинаковой длины и найдите их сумму, разность, произведение
- Найдите среднее, медиану, дисперсию и стандартное отклонение
Задача 3¶
На вход дан одномерный массив $X$. Напишите функцию, которая выдает на вход массив из кумулятивных средних массива $X$. Иначе говоря, если $X = \left(x_1, x_2, \ldots, x_n\right)$, то ответ должен быть равен $s = \left(s_1, s_2, \ldots, s_n\right)$, где $s_k=\frac{x_1+...+x_k}{k}$.
Подсказка (кликни)
Вам поможет функция cumsum
Пример: [15, 7, 22, 11, 30, 5, 18] -> [15.0, 11.0, 14.66666667, 13.25, 15.0, 12.66666667, 13.71428571]
sample = [4, 23, 69, 90, 5, 45, 19, 21]
Задача 4¶
Задан массив $X$. Для массива $X$ необходимо сделать следующее преобразование.
Необходимо написать функцию transform
, которая построит новый массив, где все элементы с нечетными индексами требуется заменить на число 1. Все элементы с четными индексами нужно возвести в куб. Затем записать элементы в обратном порядке относительно их позиций.
Пример: [3, 1, 4, -1, 2, 3, 0] -> [27, 1, 64, 1, 8, 1, 0] -> [0, 1, 8, 1, 64, 1, 27]
sample = [56, 20, 12, 10, 6, 84, 39, 57]
Задача 5¶
Сгенерируйте два вектора a
и b
в трехмерном пространстве. Заполните их случайными числами. Реализуйте их скалярное произведение с помощью numpy
.
Подсказка (кликни)
Для генерации можно использовать np.random.sample
def no_numpy_scalar(v1, v2):
"""
v1: list[n] --- первый вектор-аргумент длиной n
v2: list[n] --- второй вектор-аргумент длиной n
return c: float --- результат скалярного произведения векторов v1 и v2
Функция принимает на вход два вектора длиной n
Возвращает число, равное их скалярному произведению v1 и v2
Реализуйте скалярное умножение векторов, не используя функции из пакета numpy
"""
result = sum(x * y for x, y in zip(v1, v2))
return result
def numpy_scalar(v1, v2):
"""
v1: np.array[n] --- первый вектор-аргумент длиной n
v2: np.array[n] --- второй вектор-аргумент длиной n
return c: float --- результат скалярного произведения векторов v1 и v2
Функция принимает на вход два вектора длиной n
Возвращает число, равное их скалярному произведению
Реализуйте скалярное умножение векторов, используя функции из пакета numpy
"""
result = ...
return result
# Генерация векторов
a = ...
b = ...
product_1 = no_numpy_scalar(a, b)
product_2 = numpy_scalar(a, b)
# проверим корректность:
assert np.allclose(product_1, product_2)
%time product_1 = no_numpy_scalar(a,b)
%time product_2 = numpy_scalar(a,b)
Задача 6¶
Для генерации матриц используем модуль random — он используется для генерации случайных объектов, функция sample создает случайную выборку. В качестве аргумента ей передается кортеж $\left(i,j\right)$, здесь $i$ — число строк, $j$ — число столбцов.
Выведите размерность (ранг) каждой матрицы с помощью функции ndim
. Используйте функцию shape
, что она вывела? Посмотрите на тип переменной, и сравните с типом объекта numpy
созданной с помощью функции matrix
a = np.random.sample((100, 100))
b = np.random.sample((100, 100))
...
Задача 7¶
Рассмотрим 3D-массив sales_data
размером (4, 3, 5)
, который хранит данные о продажах.
Оси массива:
0
— разные регионы (4 региона)1
— разные товары (3 вида товаров)2
— продажи за 5 месяцев
Пример данных:
sales_data = np.random.randint(50, 200, size=(4, 3, 5))
Кроме того, имеется 2D-массив discounts
размером (4, 3)
, который хранит скидки (в виде коэффициента, например, 0.9
означает скидку $10\%$) для каждого товара в каждом регионе:
discounts = np.array(
[
[0.9, 0.85, 0.95],
[0.88, 0.92, 0.87],
[0.93, 0.89, 0.91],
[0.86, 0.94, 0.90],
]
)
Примените скидки ко всем месяцам продаж используя broadcasting, чтобы скорректировать sales_data
.
Вычислить общую сумму продаж после скидок для каждого региона (результат должен быть размерности (4,)
).
Задача 8¶
Вам предлагается перемножить две квадратные матрицы двумя способами — без использования пакета numpy
и с ним.
def no_numpy_mult(a, b):
"""
A: list of "size" lists, each contains "size" floats --- первая матрица-аргумент
B: list of "size" lists, each contains "size" floats --- вторая матрица-аргумент
return C: list of "size" lists, each contains "size" floats --- матрица, являющаяся результатом умножения матриц a и b
Функция принимает на вход две матрицы: A и B размерностью size x size
Возвращает матрицу их произведения A * B = C
"""
size = len(a)
result = [[0] * size for _ in range(size)]
for i in range(size):
for j in range(size):
for k in range(size):
result[i][j] += a[i][k] * b[k][j]
return result
def numpy_mult(a, b):
"""
A: np.ndarray[size, size] --- первая матрица-аргумент
B: np.ndarray[size, size] --- вторая матрица-аргумент
return C: np.array[size, size] --- матрица, являющаяся результатом умножения матриц A и B
Функция принимает на вход две матрицы: A и B размерностью size x size
Возвращает матрицу их произведения A * B = C
Реализуйте умножение матриц, используя функции из пакета numpy
"""
pass
Проверьте корректность и сравните время выполнения.
M1 = no_numpy_mult(a, b)
M2 = numpy_mult(a, b)
# проверим корректность
assert np.allclose(np.array(M1), M2)
%time no_numpy_mult(a, b)
%time numpy_mult(a, b)
Задача 9¶
Создайте случайно заполненную матрицу 5x5 и проведите следующие действия с ней:
- Транспонирование
- Нахождение детерминанта
- Нахождение обратной матрицы
- Создайте и объедините 2 матрицы сначала по столбцу, а потом по строкам
- Разбейте исходную матрицу
matrix = ...
transposed_matrix = ...
det = ...
inv_matrix = ...
print("Исходная матрица:\n", matrix)
print("Транспонированная матрица:\n", transposed_matrix)
print("Определитель:\n", det)
print("Обратная матрица:\n", inv_matrix)
coancated_matrix_col = ...
coancated_matrix_row = ...
splited_matrix_col = ...
coancated_matrix_row = ...
print("Объединение по столбцу\n", coancated_matrix_col)
print("Объединение по строке\n", coancated_matrix_row)
print("Разбитая матрица по столбцу\n", splited_matrix_col)
print("Разбитая матрица по строке\n", coancated_matrix_row)
Библиотеки matplotlib
и seaborn
¶
Задача 1¶
Нарисуйте график синусоидальной волны для диапазона значений от 0 до $2\pi$. Добавьте заголовок, метки осей и сетку.
Создайте массива значений от 0 до $2\pi$ и вычислите синус для каждого значения в массиве.
Подсказка (кликни)
Используйте функции np.linspace
для создания массива значений и np.sin
для вычисления синуса.
...
Постройте график
...
Задача 2¶
Сгенерируйте 1000 случайных чисел и постройте гистограмму их распределения.
...
Задача 3¶
Создайте массив sizes
, который будет состоять из $10^2, 10^3, 10^4, 10^5$ чисел. Числа должны быть целыми.
Постройте plt.subplots
в виде строки из 4 графиков. Параметр bins
укажите 100. На каждом графике нарисуйте гистограмму массива заданного размера из массива sizes
. Подпишите, какой размер массивы к какому графику относится.
Подсказка
Для создания массива можно воспользоваться np.logspace
Подписи осей создаются как axs[i].set('параметры')
sizes = ...
fig, axs = plt.subplots(figsize="размеры графика", ncols="колличество колонок")
...
plt.show()
Задача 4¶
Создайте анимацию, показывающую распространение волны в двумерной плоскости. Волна должна начинаться из центра и распространяться во все стороны. Используйте цветовую карту для визуализации амплитуды волны.
Требования:
- Используйте библиотеку matplotlib для создания анимации.
- Волна должна быть синусоидальной.
- Анимация должна показывать распространение волны от центра к краям.
- Используйте цветовую карту для визуализации амплитуды волны.
- Добавьте заголовок и цветовую шкалу.
Подсказка
Используйте numpy.meshgrid
для создания сетки координат.
Используйте matplotlib.animation.FuncAnimation
для создания анимации.
Используйте matplotlib.pyplot.imshow
или matplotlib.pyplot.pcolormesh
для визуализации волны.
Для начала построим статическую картину распределения
# Параметры волны
size = ... # размер сетки
amplitude = ... # амплитуда волны
frequency = ... # частота волны
# Создаем сетку координат
x = np.linspace()
y = np.linspace()
X, Y = ...
# Функция волны
Z = ...
# Построение статического изображения
...
Теперь изменим функцию так, чтобы она обновлялась покадрово
Подсказка
Синус зависит от frames
# Параметры волны
frames = 100 # количество кадров
# Функция для обновления анимации
def update(frame):
Z = ...
cax.set_array(Z)
ax.set_title(f"Frame {frame}")
return (cax,)
import matplotlib.animation as animation
from IPython.display import HTML
# Создаем фигуру и оси
fig, ax = plt.subplots()
cax = ax.imshow(
np.zeros((size, size)), cmap="viridis", extent=(-5, 5, -5, 5), animated=True
)
fig.colorbar(cax, ax=ax)
# Создаем анимацию
ani = animation.FuncAnimation(
fig="объект графика",
func="функция задающая распределение волны",
frames=frames,
interval=50,
blit=True,
)
# Отображаем анимацию в Colab
HTML(ani.to_jshtml())
Задача 5¶
Создайте тепловую карту корреляции для набора данных, содержащего информацию о различных характеристиках автомобилей (например, цена, мощность двигателя, расход топлива и т.д.). Визуализация должна показывать, как различные характеристики коррелируют друг с другом.
Требования:
- Используйте библиотеку Seaborn для создания тепловой карты корреляции.
- Добавьте аннотации к каждой ячейке тепловой карты, показывающие значения корреляции.
- Используйте цветовую шкалу для визуализации корреляции.
- Добавьте заголовок и метки осей.
Подсказка
Используйте pandas.DataFrame.corr
для вычисления матрицы корреляции.
Используйте seaborn.heatmap
для создания тепловой карты корреляции.
# Загрузка набора данных
data = sns.load_dataset("mpg")
# Удаление категориальных переменных
data = data.select_dtypes(include=["float64", "int64"])
# Вычисление матрицы корреляции
...
# Создание тепловой карты корреляции
...
Задача 6¶
Сгенерируйте набор данных, содержащий две переменные, и визуализируйте их с помощью scatter plot. Добавьте линию регрессии на график.
Подсказка
Используйте numpy.random.normal
для генерации данных.
Используйте seaborn.scatterplot
для построения scatter plot.
Используйте seaborn.regplot
для добавления линии регрессии.
# Генерация данных
x = ... # независимая переменная
y = 2 * x + np.random.normal(
loc=0, scale=1, size=100
) # зависимаяпеременная (таргет)
# Построение scatter plot и линии регрессии
...
Библиотека pandas
¶
Задача 1¶
Это структура данных, которую можно рассматривать как одну колонку таблицы, одномерный массив.
Создайте объект Series
на основе имеющихся данных и выведите месяц своего рождения, а также промежуток месяцев, когда бы вы хотели родиться (месяца должны быть последовательны):
Подсказка
Можно воспользоваться методами .loc
или .iloc
# Полный список месяцев
months = [
"Январь",
"Февраль",
"Март",
"Апрель",
"Май",
"Июнь",
"Июль",
"Август",
"Сентябрь",
"Октябрь",
"Ноябрь",
"Декабрь",
]
# Полный список индексов
indexes = [
"Первый",
"Второй",
"Третий",
"Четвёртый",
"Пятый",
"Шестой",
"Седьмой",
"Восьмой",
"Девятый",
"Десятый",
"Одиннадцатый",
"Двенадцатый",
]
# Создание Series
...
Задача 2¶
Создайте
Series
с числовыми данными (случайным образом в диапазоне от 1 до 100)Вычислите среднее значение, сумму и максимальное значение
Отфильтруйте значения, которые больше заданного порога (например 30)
Задача 3¶
Создайте Series
с числовыми данными, сгенерированные случайным образом в диапазоне от 1 до 100, и примените функцию для преобразования значений (например, умножение на 2).
Подсказка
Можно использовать метод apply()
для применения функции. Однако он работает медленнее, чем векторизированные операции, поэтому им стоит пользоваться только в крайних случаях
def complex_transform(x):
...
return ...
def apply_complex_transform(series):
"""Применяет сложное преобразование к каждому элементу Series с
использованием метода apply.
Parameters:
series (pd.Series): Входная Series с числовыми данными.
Returns:
pd.Series: Преобразованная Series.
"""
return ...
def vectorized_operation(series):
"""Выполняет векторизированную операцию умножения всех элементов Series на 2.
Parameters:
series (pd.Series): Входная Series с числовыми данными.
Returns:
pd.Series: Преобразованная Series.
"""
return ...
Проверим работу и время выполнения
# Создание объекта Series
...
# Результаты преобразований
...
# Замеряем время выполнения функции с apply
%%time
transformed_series_apply = apply_complex_transform(series)
# Замеряем время выполнения векторизированной операции
%%time
transformed_series_vectorized = vectorized_operation(series)
Задача 4¶
Пусть есть два объекта Series
, содержащих данные о продажах за два разных месяца. Объедините эти данные и визуализируйте их с помощью линейного графика, чтобы показать изменение продаж по дням.
Подсказка
Для улучшения визуализации можно воспользоваться plt.xticks
Для объединения даты можно воспользоваться pd.concat
# Создание данных о продажах за первый месяц
sales_january = pd.Series(
[100, 150, 200, 250, 300, 350, 400],
index=pd.date_range(start="2023-01-01", periods=7, freq="D"),
)
# Создание данных о продажах за второй месяц
sales_february = pd.Series(
[450, 500, 550, 600, 650, 700, 750],
index=pd.date_range(start="2023-02-01", periods=7, freq="D"),
)
# Объединение данных
...
Задача 5¶
Объект DataFrame
лучше всего объяснять на примере обычной таблицы. В таблице есть строки и столбцы. Столбцами в объекте DataFrame
выступают объекты Series
, а их элементы будут строками.
Создайте объект DataFrame
. Проще всего сделать это из словаря, в котором ключ это название колонки, значения — данные массива. Данные могут быть как текстового так и числового вида.
Задача 7¶
Повторите задания 2—3 из этого блока, но только для объекта DataFrame
, с соответствующими методами
Задача 8¶
Пусть есть DataFrame
, содержащий данные о продажах различных товаров в нескольких категориях. Вычислите общую сумму продаж для каждой категории и визуализируйте результаты с помощью столбчатой диаграммы.
Подсказка
Используйте метод groupby()
для применения функции.
data = pd.DataFrame(
{
"Category": [
"Electronics",
"Books",
"Electronics",
"Books",
"Furniture",
"Electronics",
"Furniture",
],
"Sales": [100, 150, 200, 250, 300, 350, 400],
}
)
...
Задача 9¶
Пусть есть два DataFrame
, содержащих данные о продажах и клиентах. Объедините эти данные по общему ключу и визуализируйте распределение продаж по возрасту клиентов.
# Создание DataFrame с данными о продажах
sales_data = pd.DataFrame(
{"ClientID": [1, 2, 3, 4, 5], "Sales": [100, 150, 200, 250, 300]}
)
# Создание DataFrame с данными о клиентах
clients_data = pd.DataFrame(
{"ClientID": [1, 2, 3, 4, 5], "Age": [25, 30, 35, 40, 45]}
)
...
Задача 10¶
Пусть есть DataFrame
, содержащий данные о различных характеристиках автомобилей. Вычислите корреляционную матрицу и визуализируйте её с помощью тепловой карты
# Создание DataFrame с данными о характеристиках автомобилей
np.random.seed(0) # Для воспроизводимости результатов
data = pd.DataFrame(
{
"Price": np.random.randint(20000, 50000, size=100),
"Mileage": np.random.randint(1000, 50000, size=100),
"Horsepower": np.random.randint(100, 400, size=100),
"FuelEfficiency": np.random.randint(15, 40, size=100),
"Age": np.random.randint(1, 10, size=100),
}
)
...
Что можно сказать исходя из полученного рисунка?