УМК СПО

Учебно-методические комплексы

для преподавателей СПО








Объединение, слияние и работа с пропусками в Pandas

ОП.09 Обработка и анализ данных
Практическая работа №4
Тема: Объединение, слияние и работа с пропусками в Pandas

Цель работы: Научиться объединять несколько датафреймов, выполнять слияние по ключевым полям, обрабатывать пропущенные значения различными методами.
Время выполнения: 2 академических часа
Инструменты: Python + Jupyter Notebook, библиотеки pandas, numpy

ЗАДАНИЕ ДЛЯ СТУДЕНТА

Этап 1. Создание нескольких датафреймов (10 минут)

Создадим три датафрейма для демонстрации объединения:



import pandas as pd
import numpy as np

# Датафрейм 1: студенты и их группы
students = pd.DataFrame({
'student_id': [1, 2, 3, 4, 5],
'name': ['Анна', 'Борис', 'Виктор', 'Галина', 'Дмитрий'],
'group': ['ИС-21', 'ИС-21', 'ИС-22', 'ИС-22', 'ИС-23']
})
print("Студенты:")
print(students)

# Датафрейм 2: оценки по предметам
grades = pd.DataFrame({
'student_id': [1, 2, 3, 4, 5, 1, 2, 3],
'subject': ['Математика', 'Математика', 'Математика', 'Математика', 'Математика',
'Физика', 'Физика', 'Физика'],
'score': [5, 4, 3, 5, 4, 4, 3, 4]
})
print("Оценки:")
print(grades)

# Датафрейм 3: дополнительная информация
extra = pd.DataFrame({
'student_id': [1, 2, 6, 7],
'email': ['anna@edu.ru', 'boris@edu.ru', 'ivan@edu.ru', 'olga@edu.ru']
})
print("Доп. информация:")
print(extra)



Этап 2. Объединение строк (concat) (10 минут)

Используйте concat для вертикального и горизонтального объединения:



# Вертикальное объединение (добавляем строки)
students2 = pd.DataFrame({
'student_id': [6, 7],
'name': ['Елена', 'Жанна'],
'group': ['ИС-23', 'ИС-24']
})
all_students = pd.concat([students, students2])
print("Все студенты (вертикальное объединение):")
print(all_students)

# Горизонтальное объединение (добавляем столбцы)
more_info = pd.DataFrame({
'city': ['Москва', 'СПб', 'Казань', 'НН', 'Екб'],
'age': [19, 20, 21, 20, 19]
})
students_with_city = pd.concat([students, more_info], axis=1)
print("Студенты с городом (горизонтальное объединение):")
print(students_with_city)



Вопрос: Что произойдёт, если при горизонтальном объединении количество строк разное?

Этап 3. Слияние таблиц (merge) (15 минут)

Выполните различные типы слияний:



# Inner join (только те, у кого есть оценки)
inner_merge = pd.merge(students, grades, on='student_id', how='inner')
print("Inner join (только студенты с оценками):")
print(inner_merge)

# Left join (все студенты)
left_merge = pd.merge(students, grades, on='student_id', how='left')
print("Left join (все студенты, оценки где есть):")
print(left_merge)

# Right join (все оценки)
right_merge = pd.merge(students, grades, on='student_id', how='right')
print("Right join (все оценки):")
print(right_merge)

# Outer join (все данные из обеих таблиц)
outer_merge = pd.merge(students, extra, on='student_id', how='outer')
print("Outer join (все студенты + доп. контакты):")
print(outer_merge)



Вопросы:
• Какой тип слияния сохраняет всех студентов, даже если у них нет оценок?
• Что появится в ячейках при отсутствии данных в left/right merge?

Этап 4. Работа с пропусками (NaN) (20 минут)

Создадим датафрейм с пропусками и научимся их обрабатывать:



# Создаём данные с пропусками
df_with_nan = pd.DataFrame({
'name': ['Анна', 'Борис', 'Виктор', 'Галина', 'Дмитрий'],
'math': [5, 4, np.nan, 5, 4],
'physics': [4, np.nan, 3, 5, np.nan],
'informatics': [5, 5, 4, np.nan, 4]
})
print("Исходные данные с пропусками:")
print(df_with_nan)

# 1. Проверка на пропуски
print("Сколько пропусков в каждом столбце:")
print(df_with_nan.isnull().sum())

# 2. Удаление строк с пропусками
dropped_rows = df_with_nan.dropna()
print("После удаления всех строк с пропусками:")
print(dropped_rows)

# 3. Заполнение пропусков средним значением
df_filled_mean = df_with_nan.copy()
df_filled_mean['math'] = df_filled_mean['math'].fillna(df_filled_mean['math'].mean())
df_filled_mean['physics'] = df_filled_mean['physics'].fillna(df_filled_mean['physics'].mean())
df_filled_mean['informatics'] = df_filled_mean['informatics'].fillna(df_filled_mean['informatics'].mean())
print("После заполнения средним значением:")
print(df_filled_mean)

# 4. Заполнение пропусков заданным значением
df_filled_value = df_with_nan.fillna(0)
print("После заполнения нулями:")
print(df_filled_value)

# 5. Заполнение пропусков предыдущим значением (ffill)
df_ffill = df_with_nan.fillna(method='ffill')
print("После заполнения предыдущим значением:")
print(df_ffill)



Вопросы:
• Какой метод заполнения лучше использовать для числовых данных?
• В каких случаях уместно удалять строки с пропусками?

Этап 5. Практическое задание: объединение данных о фильмах (20 минут)

Даны две таблицы с информацией о фильмах и рейтингах:



# Таблица фильмов
movies = pd.DataFrame({
'movie_id': [1, 2, 3, 4, 5],
'title': ['Побег из Шоушенка', 'Крёстный отец', 'Тёмный рыцарь', 'Криминальное чтиво', 'Властелин колец'],
'year': [1994, 1972, 2008, 1994, 2001]
})
print("Фильмы:")
print(movies)

# Таблица рейтингов (с пропусками)
ratings = pd.DataFrame({
'movie_id': [1, 2, 3, 4, 5, 1, 2, 3, 4],
'user_id': [101, 101, 101, 101, 101, 102, 102, 102, 102],
'rating': [9.5, 9.0, 9.0, 8.5, np.nan, 9.0, 8.5, 8.0, 9.0]
})
print("Рейтинги:")
print(ratings)



Выполните задания:



# 1. Объедините movies и ratings, чтобы получить полную информацию о каждом рейтинге
full_ratings = pd.merge(ratings, movies, on='movie_id', how='left')
print("Полная информация о рейтингах:")
print(full_ratings)

# 2. Рассчитайте средний рейтинг для каждого фильма (предварительно удалив пропуски)
clean_ratings = ratings.dropna()
avg_rating = clean_ratings.groupby('movie_id')['rating'].mean()
print("Средний рейтинг каждого фильма:")
print(avg_rating)

# 3. Добавьте средний рейтинг к таблице фильмов
movies_with_rating = pd.merge(movies, avg_rating.reset_index(), on='movie_id', how='left')
movies_with_rating.rename(columns={'rating': 'avg_rating'}, inplace=True)
print("Фильмы со средним рейтингом:")
print(movies_with_rating)

# 4. Заполните пропуски среднего рейтинга (если нет оценок) значением 0
movies_with_rating['avg_rating'] = movies_with_rating['avg_rating'].fillna(0)
print("После заполнения пропусков:")
print(movies_with_rating)



Вопрос: Почему при расчёте среднего рейтинга нужно удалять пропуски?

Этап 6. Работа с реальным датасетом (20 минут)

Вернёмся к датасету titanic.csv и выполним дополнительные операции:



# Загружаем датасет
df = pd.read_csv('titanic.csv')

# 1. Сколько пропусков в каждом столбце?
print("Пропуски в titanic.csv:")
print(df.isnull().sum())

# 2. Удалите столбцы с большим количеством пропусков (> 500)
# Cabin имеет 687 пропусков — удалим его
df_clean = df.drop('Cabin', axis=1)

# 3. Заполните пропуски в Age средним значением
df_clean['Age'] = df_clean['Age'].fillna(df_clean['Age'].mean())

# 4. Заполните пропуски в Embarked наиболее частым значением
most_common = df_clean['Embarked'].mode()[0]
df_clean['Embarked'] = df_clean['Embarked'].fillna(most_common)

# 5. Проверьте, остались ли пропуски
print("Пропуски после обработки:")
print(df_clean.isnull().sum())



Этап 7. Выводы (10 минут)

Напишите развёрнутый вывод по работе:
1. В чём разница между concat и merge?
2. Какие типы слияний (inner, left, right, outer) существуют и когда их применяют?
3. Какие методы обработки пропусков вы использовали? Какой метод подходит для разных ситуаций?
4. Почему важно правильно обрабатывать пропуски перед анализом данных?

КРИТЕРИИ ОЦЕНКИ

КритерийМакс. балл
Все этапы выполнены (1-6)3
Корректное использование concat и merge2
Правильная обработка пропусков (разными методами)2
Практическое задание выполнено верно1
Выводы осмысленные, примеры из работы2
Итого10


ОТВЕТ ДЛЯ ПРЕПОДАВАТЕЛЯ (эталонный результат)


Нажмите, чтобы увидеть ответы
Этап 2. concat:
• При горизонтальном объединении с разным количеством строк появится NaN.

Этап 3. merge:
• Left join сохраняет всех студентов, даже без оценок.
• При отсутствии данных появляется NaN.

Этап 4. Обработка пропусков:
• Для числовых данных лучше подходит заполнение средним/медианой.
• Удаление строк уместно, если пропусков мало (менее 5%) и данные не критичны.

Этап 5. Фильмы:
• Пропуски удаляют, потому что среднее от NaN даёт NaN.

Этап 6. Titanic:
• До обработки пропуски: Age (177), Cabin (687), Embarked (2).
• После обработки пропусков нет ни в одном столбце.

Этап 7. Выводы (пример):
1. Concat — простое склеивание строк/столбцов, merge — слияние по ключу.
2. Inner — пересечение, left/right — с приоритетом одной таблицы, outer — всё.
3. Использовали: dropna, fillna(mean), fillna(value), ffill.
4. Без обработки пропусков многие функции (mean, groupby) работают некорректно.


Автор: УМК СПО
Лицензия: Бесплатное использование с указанием источника





Логин: Пароль: Забыли пароль?Регистрация

Самозанятый: Стешенко Светлана Николаевна ИНН: 231408226339

Актуальная версия — 2026
Сайт сделан на SiNG cms © 2010-2020