Собесов

Сценарий: стратегии обработки NaN — когда что

PythonОчистка данныхСредняяMiddle

Условие

В датасете users(age, income, city, last_login) пропуски в каждой колонке. Опиши стратегии и где какая уместна.

Решение

Сначала разобраться, почему пропуск

  • MCAR (missing completely at random) — случайно: можно удалять или импьютировать чем угодно.
  • MAR (missing at random) — зависит от других колонок: модельная импьютация.
  • MNAR (not at random) — пропуск сам по себе сигнал: добавить флаг is_missing.

Стратегии

Колонка Стратегия Почему
age (числ.) медиана по сегменту, + флаг устойчиво к выбросам
income (числ., скошенное) медиана + флаг is_missing MNAR: «не сказали» = сигнал
city (категория) «Unknown» категория не теряем строки
last_login (дата) оставить NaN или max(date) NaN = «не логинился» — это важная инфа

Реализация

import pandas as pd
import numpy as np
 
# Флаг пропуска как фича
for c in ['age', 'income']:
    df[f'{c}_is_missing'] = df[c].isna().astype(int)
 
# Медиана по сегменту
df['age'] = df.groupby('city')['age'].transform(lambda s: s.fillna(s.median()))
df['income'] = df.groupby('city')['income'].transform(lambda s: s.fillna(s.median()))
 
# Категория
df['city'] = df['city'].fillna('Unknown')
 
# Без импьютации — оставить NaN как сигнал
# df['last_login'] остаётся NaN

Когда удалять строки

  • Пропусков в колонке >50% и нет хороших прокси → колонку дропнуть.
  • Пропусков в target → строки выкинуть (для ML).
  • Иначе — не удалять, импьютировать + флаг.

Подводные камни

  1. fillna(mean) ломает дисперсию и корреляции. Медиана безопаснее. Идеально — модельная (KNNImputer/IterativeImputer).
  2. Импьютация до train/test split = leakage. Считать статистики только на train, применять к test.
  3. dropna() без subset= дропнет строки, где есть NaN в любой колонке — обычно слишком много.
  4. NaN в индексе/ключе merge: матчей не будет, но строки не пропадут. Контролировать indicator=True.
  5. Pandas-NaN ≠ numpy-NaN ≠ NaT (для дат). isna() ловит все три, но арифметика — нет.

Эталонный ответ

Сначала понять MCAR/MAR/MNAR, потом: числовые — медиана по сегменту + флаг, категориальные — «Unknown», даты — часто оставить NaN. Импьютацию считать только на train.

Хочешь увидеть разбор?

Зарегистрируйся бесплатно — откроется развёрнутое решение этой задачи и ещё 4 на выбор.

Зарегистрироваться и увидеть разбор
Уже есть аккаунт? Войти