Лабораторная работа №1: Python Refresher и Векторизация с NumPy
Цель: Освежить навыки владения Python и научиться мыслить "векторно". Мы откажемся от медленных циклов for при работе с числами и перейдем на эффективные операции библиотеки NumPy. Это фундамент для дальнейшей работы с Pandas и моделями машинного обучения.
Инструменты:
- Python 3 (List comprehensions, lambda)
- NumPy (Arrays, Broadcasting, Masking)
Часть 1: Python Refresher
В Data Science мы ценим лаконичность. Код должен быть читаемым и компактным.
Задание 1.1: Дан список "сырых" строк (например, названия файлов или столбцов CSV).
Задача:
- Привести все строки к нижнему регистру.
- Удалить пробелы в начале и конце.
- Оставить только те строки, которые содержат подстроку
data. - Сделать это одной строкой кода, используя List Comprehension.
import numpy as np
raw_files = [
" Log_Data_2023.csv ",
"image_001.jpg",
" CONFIG.XML ",
"data_preprocessing.py",
"Sales_Data_Final.xlsx",
"readme.md"
]
# TODO: Ваш код здесь. Результат сохраните в clean_files
# clean_files = ...
print(f"Исходный список: {raw_files}")
# Ожидаемый результат: ['log_data_2023.csv', 'data_preprocessing.py', 'sales_data_final.xlsx']
# print(f"Обработанный список: {clean_files}")Часть 2: Введение в NumPy
Списки Python — это медленно и дорого по памяти. Переходим к ndarray.
Задание 2.1: Создание массивов и формы
Задача:
- Создайте матрицу
Aразмера , заполненную случайными числами (используйтеnp.random.rand). - Создайте матрицу
B, состоящую только из единиц, такого же размера, какA. - Выведите атрибуты
shape,sizeиdtypeматрицыA.
# TODO: Ваш код здесь
# A = ...
# B = ...
# print(f"Shape: {A.shape}")
# print(f"Size: {A.size}")
# print(f"Dtype: {A.dtype}")Важное правило NumPy
Использование циклов for для обхода элементов массива ndarray в NumPy категорически не рекомендуется, так как это сводит на нет все преимущества векторизации и производительности библиотеки.
Часть 3: Broadcasting и Masking
Это "суперсилы" NumPy.
Задание 3.1: Нормализация данных (Min-Max Scaling)
В ML часто нужно приводить признаки к диапазону [0, 1]. Формула:
Пусть у нас есть матрица X (), где строки — это объекты, а столбцы — признаки (например: Рост, Вес, Возраст).
Задача: Нормализовать каждый столбец отдельно, используя Broadcasting.
np.random.seed(42) # Фиксируем random state для воспроизводимости
X = np.random.randint(0, 100, (10, 3))
print("Исходная матрица X (первые 5 строк):")
print(X[:5])
# TODO: Найдите минимум и максимум ДЛЯ КАЖДОГО СТОЛБЦА (axis=0)
# min_vals = ...
# max_vals = ...
# TODO: Примените формулу Min-Max Scaling (Broadcasting сработает автоматически)
# X_norm = ...
# print("\nНормализованная матрица X_norm (первые 5 строк):")
# print(X_norm[:5])
# Проверка: минимумы столбцов должны стать 0, максимумы 1
# print("\nПроверка (Min/Max столбцов X_norm):")
# print(X_norm.min(axis=0), X_norm.max(axis=0))Задание 3.2: Фильтрация по условию (Masking)
Вам нужно найти выбросы или отобрать специфические данные.
Задача:
- Создайте массив
salesиз 100 случайных чисел (нормальное распределение: среднее 1000, стд 200). - Найдите все значения, которые отклоняются от среднего более чем на 1.5 стандартных отклонения (выбросы).
- Замените эти выбросы на значение среднего (imputation).
sales = np.random.normal(1000, 200, 100)
# TODO: Вычислите границы
mean_val = np.mean(sales)
std_val = np.std(sales)
# TODO: Создайте булеву маску для выбросов ( |x - mean| > 1.5 * std )
# outliers_mask = ...
print(f"Найдено выбросов: {np.sum(outliers_mask)}")
# TODO: Используйте маску для замены значений в sales
# sales_clean = sales.copy()
# sales_clean[...] = ...
# print("Данные очищены.")