Как заполнить пропущенные значения в pandas

Введение
Очистка данных занимает большую часть времени в проектах с данными. Пропущенные значения (NaN) и пустые ячейки часто мешают анализу и обучению моделей. pandas — основной инструмент в Python для манипуляций с табличными данными. Он предлагает простые и гибкие способы заполнить или заменить пропуски.
В этой статье вы получите практическое руководство по нескольким подходам к импутации в pandas. Примеры используют DataFrame, похожий на реальную небольшую выборку, и моменты, когда один метод предпочтительнее другого.
Подготовка окружения и пример данных
Установите pandas в виртуальное окружение командой:
pip install pandasМожно работать с любым источником: CSV, Excel, базой данных. Для примера используем смоделированный DataFrame с пропусками.
import pandas as pd
import numpy as np
df = pd.DataFrame({
'A': [0, 3, np.nan, 10, 3, np.nan],
'B': [np.nan, np.nan, 7.13, 13.82, 7, 7],
'C': [np.nan, "Pandas", np.nan, "Pandas", "Python", "JavaScript"],
'D': ["Sound", np.nan, np.nan, "Music", "Songs", np.nan]
})
print(df)Короткие определения терминов:
- Пропуск (NaN): отсутствующее значение в ячейке DataFrame.
- Импутация: процесс заполнения пропусков значениями.
Основные методы в pandas
Ниже — практические способы заполнить пропущенные значения. Для каждого метода указаны плюсы и минусы и примеры кода.
1. fillna(): простая и гибкая замена
fillna заполняет пропуски указанным значением или значениями по колонкам. Подходит для массовых замен и быстрой корректировки DataFrame.
Ключевые параметры:
- value — значение или словарь {столбец: значение} для замены.
- method — ‘ffill’ или ‘bfill’ для копирования соседних значений.
- inplace — если True, изменяет исходный DataFrame.
Заполнение средним, медианой, модой
Для числовых столбцов удобно вставлять mean/median. Для строковых — mode.
# Вставить среднее по числовым столбцам
df.fillna(df.mean(numeric_only=True).round(1), inplace=True)
# Вставить медиану по числовым столбцам
df.fillna(df.median(numeric_only=True).round(1), inplace=True)
print(df)Примечание: numeric_only=True гарантирует, что средние считаютcя только по числовым колонкам.
Чтобы заполнить строковые столбцы модой:
string_columns = df.select_dtypes(include=['object']).columns
# mode() может вернуть DataFrame, поэтому берем первую строку
df[string_columns] = df[string_columns].fillna(df[string_columns].mode().iloc[0])
# Или конкретно по столбцу C:
df['C'].fillna(df['C'].mode()[0], inplace=True)Можно комбинировать правила по столбцам:
df.fillna({
'A': df['A'].mean(),
'B': df['B'].median(),
'C': df['C'].mode()[0]
}, inplace=True)
print(df)Плюсы: простота, прозрачность. Минусы: затирает распределение, если замена однотипная.
2. Метод ffill и bfill
Forward-fill (ffill) копирует значение сверху вниз. Backward-fill (bfill) — снизу вверх. Полезно для временных рядов или когда соседние значения логично продолжать.
# Заполнить значениями выше
df.fillna(method='ffill', inplace=True)
# Или заполнить значениями ниже
df.fillna(method='bfill', inplace=True)Часто используют ffill, затем bfill, чтобы заполнить обе стороны:
df.fillna(method='ffill', inplace=True)
df.fillna(method='bfill', inplace=True)Плюсы: сохраняет локальную согласованность. Минусы: может повторять аномалии и не подходит, если пропуски большие по длине.
3. replace(): замена любых значений
replace полезен, когда нужно заменить не только NaN, но и другие маркеры отсутствия (‘’, ‘NA’, -999 и т. п.).
# Пример: заменить np.nan в колонке A на среднее
df['A'].replace([np.nan], df['A'].mean(), inplace=True)replace поддерживает словари и регулярные выражения. Используйте, если данные содержат кастомные метки отсутствия.
4. interpolate(): числовая интерполяция
interpolate вычисляет недостающие значения на основе соседних чисел. Подходит для числовых рядов с естественным порядком.
# Линейная интерполяция, направление backward или forward
df.interpolate(method='linear', limit_direction='backward', inplace=True)
df.interpolate(method='linear', limit_direction='forward', inplace=True)Плюсы: сохраняет тренды, хорошо для временных рядов. Минусы: не подходит для категориальных данных.
Дополнительные подходы и альтернативы
5. Удаление строк или столбцов (dropna)
Иногда проще удалить строки или столбцы с пропусками. Удаление оправдано, если доля пропусков мала и удаление не приведёт к смещению выборки.
# Удалить строки с любыми NaN
df.dropna(axis=0, how='any', inplace=True)
# Удалить столбцы, где больше чем 50% пропущено
threshold = len(df) * 0.5
df.dropna(axis=1, thresh=threshold, inplace=True)Важно: перед удалением проанализируйте, какие записи вы потеряете.
6. Импутация с помощью sklearn (SimpleImputer и IterativeImputer)
Для моделей можно использовать sklearn.impute.SimpleImputer или IterativeImputer из sklearn. Они помогают строить более осмысленные замены и интегрируются в pipeline.
from sklearn.impute import SimpleImputer
import numpy as np
imp_mean = SimpleImputer(missing_values=np.nan, strategy='mean')
num_cols = df.select_dtypes(include=[np.number]).columns
df[num_cols] = imp_mean.fit_transform(df[num_cols])IterativeImputer (многомерная импутация) строит модель для предсказания пропусков на основе остальных признаков. Он мощнее, но медленнее.
7. Модельные методы и специальные библиотеки
- Используйте KNNImputer для заполнения на основе близких наблюдений.
- Для сложных форм пропусков подходят модели типа MICE (многократная имputation).
- Библиотеки: fancyimpute, missingpy — реализуют дополнительные алгоритмы.
Когда метод не подойдёт (контрпримеры)
- fillna(mean) может искажать дисперсию и снизить эффективность моделей, чувствительных к распределению.
- ffill/bfill плохи, если пропуск длинный и предыдущие/последующие значения не релевантны.
- Interpolate не применим к категориальным данным.
- Удаление строк опасно при системных пропусках (например, пропуски зависят от целевой переменной).
Всегда проверяйте изменения с помощью визуализации и статистик (mean, std, распределение).
Практическая методология: как принять решение
Мини-методология (шаги):
- Оцените долю пропусков по колонкам.
- Проверьте, зависят ли пропуски от других признаков (Missingness pattern).
- Для чисел: визуализируйте распределение и решите — mean/median/interpolate/model.
- Для категорий: рассмотрите mode или специальную метку ‘Unknown’.
- Оцените влияние на модель через валидацию.
Mermaid: простое дерево решений для выбора метода
flowchart TD
A[Есть пропуски?] -->|Нет| B[Ничего не делать]
A -->|Да| C[Тип данных]
C -->|Числовые| D{Доля пропусков}
C -->|Категориальные| E{Доля пропусков}
D -->|Мала '<5%'| F[fillna'mean/median']
D -->|Средняя| G[interpolate / SimpleImputer / model]
D -->|Большая| H[удалить столбец или специальная имputation]
E -->|Мала| I[mode или замена на 'Unknown']
E -->|Большая| J[групповая замена или удаление]Ролевые чек-листы
Аналитик:
- Проверить процент пропусков.
- Построить гистограммы и boxplot для чисел.
- Протестировать fillna(mean) и fillna(median).
Data Scientist:
- Оценить зависимость пропусков от таргета.
- Попробовать IterativeImputer/KNN.
- Проверить стабильность метрик на валидации.
Инженер данных:
- Очистить источники данных.
- Стандартизировать метки отсутствия (NA, ‘’, -999).
- Зафиксировать правила в ETL pipeline.
Критерии приёмки
- Входной датасет не содержит NaN в тех столбцах, где это критично.
- Импутация не ухудшает метрики на проверочном наборе данных.
- Правила импутации задокументированы и воспроизводимы.
Короткий глоссарий (1 строка)
- Импутация: заполнение пропущенных значений на основе правил или моделей.
Риски и рекомендации
- Не используйте одну стратегию для всех колонок без анализа.
- Визуализируйте данные до и после импутации.
- Для production — фиксируйте pipeline и версии библиотек.
Часто задаваемые вопросы
Можно ли заменять NaN на 0?
Да, но это допустимо, только если 0 логично для признака (например, количество предметов). Иначе 0 может исказить анализ.
Как выбрать mean или median?
Если распределение нормально и без сильных выбросов — mean. При наличии выбросов — median.
Что делать с пропусками в категориальных признаках?
Часто используют mode, метку “Unknown” или создают отдельную категорию, означающую отсутствие данных.
Краткое резюме
- Выбор метода зависит от типа признака и структуры пропусков.
- Проверяйте влияние импутации на качества модели.
- Для сложных случаев применяйте модельные имутаторы или многократную импутацию.
Важное: всегда документируйте выбранный подход и сохраняйте копию необработанных данных.
Похожие материалы
Как устроить идеальную вечеринку для просмотра ТВ
Как распаковать несколько RAR‑файлов сразу
Приватный просмотр в Linux: как и зачем
Windows 11 не видит iPod — способы исправить
PS5: как настроить игровые пресеты