Контрольная пломба
После долгой очистки очень хочется посмотреть на таблицу и сказать: «Ну вот, теперь нормально». Это понятное чувство и плохой способ контроля качества. Таблица может выглядеть аккуратно и при этом содержать невозможные значения, потерянные группы или повторяющиеся строки.
Поэтому финал предобработки лучше строить не на впечатлении, а на заранее сформулированных обещаниях.
Инварианты: что обязано оставаться правдой
Инвариант — условие, которое должно выполняться для корректной таблицы после обработки. В нашем случае известные значения силы и интеллекта должны лежать в диапазоне 1–100, стоимость не может быть отрицательной, а полные дубли не должны неожиданно появиться.
assert df_clean["power"].dropna().between(1, 100).all()
assert df_clean["intelligence"].dropna().between(1, 100).all()
assert (df_clean["costume_cost"].dropna() >= 0).all()
assert not df_clean.duplicated().any()
assert не исправляет данные. Его работа скромнее и важнее: не позволить процессу тихо продолжиться, если одно из наших обещаний оказалось ложным.
Сравнение «до» и «после» — часть проверки
print("Строк:", len(df_original), "→", len(df_clean))
print("Пропуски до:")
print(df_original.isna().sum())
print("Пропуски после:")
print(df_clean.isna().sum())
Здесь нет требования, чтобы после очистки все числа стали меньше, а пропуски исчезли. Иногда NaN становится даже больше: например, после преобразования строкового unknown или невозможного значения 130 на шкале до 100. Это может быть улучшением качества, потому что проблема теперь обозначена честно.
И наконец — проверяем сам вывод
Предобработка нужна ради анализа, поэтому стоит посмотреть не только на технические свойства таблицы, но и на важные показатели. Среднее, доля объектов в группе или рейтинг категорий могут измениться. Такое изменение не доказывает ни успех, ни ошибку — оно требует объяснения.
metric_before = df_original["value"].mean()
metric_after = df_clean["value"].mean()
print(metric_before, "→", metric_after)
Если показатель изменился резко, нужно вернуться к преобразованиям и выяснить, какой шаг дал этот эффект. Возможно, мы исправили действительно искажённые значения. А возможно, вместе с ошибками незаметно удалили целую группу объектов.