Нашли ошибку?
Скачать чистый
мини-проект≈ 20 минупражнения: 0 из 4

Мини-проект: грязная выгрузка клиентов, часть 2

Продолжаем чистить выгрузку клиентов: даты в двух форматах, баллы текстом, дубли. Сверяем результат с эталоном и отвечаем маркетингу: 257 строк превращаются в 240 клиентов.

Python запустится при первом выполнении

Продолжение первой части: маркетинг ждёт, сколько клиентов в каждом городе и сколько бонусных баллов у них в среднем. Текстовые столбцы мы уже почистили, остались даты, числа и дубликаты.

Подготовка

Ячейка ниже повторяет первую часть: загружает выгрузку и чистит коды, имена, города, сегменты и почту — это решения упражнений первой части. Выполните её (или сразу первое упражнение — она выполнится сама). Последняя строка напоминает, сколько полных повторов было в сырой выгрузке: их понадобится сравнить.

[ ]Шаги первой части
import pandas as pd

customers = pd.read_csv("data/customers_raw.csv")
raw_duplicates = customers.duplicated().sum()
short = {"Спб": "Санкт-Петербург", "С.-Петербург": "Санкт-Петербург", "Екб": "Екатеринбург"}
customers["customer_id"] = customers["customer_id"].str.strip().str.upper()
customers["name"] = customers["name"].str.strip().str.replace("  ", " ").str.title()
customers["city"] = customers["city"].str.strip().str.title().replace(short)
customers["segment"] = customers["segment"].str.strip().str.lower()
customers["email"] = customers["email"].str.lower()
print("полных повторов в сырой выгрузке:", raw_duplicates)
customers.head(5)
Выводсохранённый · нажмите «Выполнить», чтобы получить свой
полных повторов в сырой выгрузке: 10
customer_id name city signup_date segment email bonus
0 C001 Сергей Ю. Екатеринбург 2025-06-12 постоянный client001@lavka.example 120
1 C002 Сергей В. Екатеринбург 2025-01-14 новый client002@lavka.example 2 400
2 C003 Максим С. Екатеринбург 2025-05-19 новый client003@lavka.example 50
3 C004 Андрей Д. Москва 2023-09-15 новый client004@lavka.example 1900
4 C005 Наталья Е. Екатеринбург 2024-08-24 постоянный NaN NaN

Шаг 1. Дата регистрации

В столбце signup_date два формата: 2025-06-12 и 24.08.2024.

[ ]Упражнение 1Две записи даты решено

Добавьте в customers столбец signup — дату регистрации настоящей датой. В no_date сохраните число строк, где даты нет.

# добавьте в customers столбец signup — дату регистрации
no_date = ...

Пропуски остались только там, где даты не было в самой выгрузке. Восстановить её неоткуда, и заполнять её чем-то «средним» нельзя: оставляем пропуск.

Шаг 2. Бонусные баллы

[ ]Что записано в bonus
print("пустых полей:", customers["bonus"].isna().sum())
customers["bonus"].value_counts().head(8)
Выводсохранённый · нажмите «Выполнить», чтобы получить свой
пустых полей: 11
bonus
0        38
50       23
450      21
800      21
300      21
нет      20
120      18
2 400    14
Name: count, dtype: int64

Числа, числа с пробелом и слово «нет». Есть и пустые поля — value_counts их не показывает, поэтому последняя строка считает их отдельно: 11 пропусков. Маркетологи подтвердили: «нет» и пустое поле значат, что баллов нет, — то есть ноль.

[ ]Упражнение 2Баллы числом решено

Добавьте в customers столбец points — баллы целым числом: пробелы между тысячами убраны, «нет» и пропуск превращены в 0. В total_points сохраните сумму баллов по всем строкам.

# добавьте в customers столбец points — бонусные баллы целым числом
total_points = ...

Шаг 3. Дубликаты

Теперь, когда текст чистый, посмотрим на повторы ещё раз:

[ ]Полных повторов и повторов по customer_id
print(customers.duplicated().sum())
print(customers.duplicated(subset=["customer_id"]).sum())
Выводсохранённый · нажмите «Выполнить», чтобы получить свой
12
17

В сырой выгрузке полных повторов было 10 (последняя строка подготовки) — стало 12, а по коду клиента их 17. Семь записей прятались за пробелами и регистром. Пять из них и сейчас не считаются полными повторами: они отличаются только записью даты в исходном столбце signup_date (2023-07-21 и 21.07.2023), который мы не меняли, а заменили столбцом signup. В итоговую таблицу возьмём только чистые столбцы.

[ ]Упражнение 3Один клиент — одна строка решено

Сохраните в clean столбцы из списка columns таблицы customers без дубликатов, отсортированные по customer_id, с индексом с нуля.

columns = ["customer_id", "name", "city", "signup", "segment", "email", "points"]
clean = ...

Шаг 4. Проверка и ответ

У магазина есть эталонный справочник клиентов — data/customers.csv. Сверим с ним результат:

[ ]Совпадает ли очищенная таблица с эталоном
reference = pd.read_csv("data/customers.csv")
print((clean["customer_id"] == reference["customer_id"]).all())
print((clean["name"] == reference["name"]).all())
print((clean["city"] == reference["city"]).all())
print((clean["segment"] == reference["segment"]).all())
Выводсохранённый · нажмите «Выполнить», чтобы получить свой
True
True
True
True

Все четыре столбца совпали. В жизни эталона обычно нет — тогда проверяют по-другому: число строк, список значений в каждом текстовом столбце, минимум и максимум в числах и датах.

[ ]Упражнение 4Ответ маркетингу решено

По таблице clean сохраните: в by_city — число клиентов в каждом городе, в wholesale — строки оптовых клиентов (сегмент «оптовый»), в avg_points — средний бонус.

by_city = ...
wholesale = ...
avg_points = ...

[ ]Итог
print("строк в выгрузке:", len(customers), "→ клиентов:", len(clean))
print("без даты регистрации:", clean["signup"].isna().sum(), "· без email:", clean["email"].isna().sum())
print("оптовых:", len(wholesale), "· средний бонус:", round(avg_points))
print(by_city)
Выводсохранённый · нажмите «Выполнить», чтобы получить свой
строк в выгрузке: 257 → клиентов: 240
без даты регистрации: 5 · без email: 43
оптовых: 26 · средний бонус: 862
city
Москва             89
Санкт-Петербург    60
Екатеринбург       39
Казань             32
Новосибирск        20
Name: count, dtype: int64
Итог появится, когда решите все упражнения урока, — в нём ответы. Ячейку можно и выполнить.

Выводы

Из 257 строк выгрузки получилось 240 клиентов. Если бы мы посчитали города по сырым данным, получили бы 22 «города» и завышенное число клиентов; если бы суммировали баллы без очистки — получили бы ошибку или потеряли треть баллов.

Выводы с ответами появятся, когда решите все упражнения урока.

Порядок, который стоит запомнить:

  1. Осмотреть: info, isna().sum(), value_counts по текстовым столбцам.
  2. Текст: пробелы, регистр, варианты написания.
  3. Типы: даты и числа — с проверкой, сколько значений не распозналось.
  4. Пропуски: решить для каждого столбца отдельно — оставить, заполнить или удалить.
  5. Дубликаты — после всего остального.
  6. Проверить результат.

Подробнее в справочнике

Практика по модулю

Задачи по pandas для самостоятельной практики появятся в разделе «Задачи → pandas».

Нашли ошибку?