isnull / dropna / fillna в pandas: шпаргалка

Карьерник — квиз-тренажёр в Telegram с 1500+ вопросами для собесов аналитика. SQL, Python, A/B, метрики. Бесплатно.

Что такое NaN в pandas

NaN (Not a Number) — стандартный способ представления пропуска в pandas. Также бывают None, NaT (для дат), pd.NA (новый тип).

import pandas as pd
import numpy as np

df = pd.DataFrame({
    'a': [1, 2, np.nan, 4],
    'b': ['x', None, 'z', 'w'],
    'c': pd.to_datetime(['2026-01-01', pd.NaT, '2026-03-01', '2026-04-01'])
})

1. Проверка пропусков

# isnull == isna (алиасы)
df.isnull()         # DataFrame булевый
df['a'].isnull()    # Series

# notnull == notna
df.notnull()
df['a'].notnull()

# есть ли NaN в колонке
df['a'].isnull().any()    # True если есть хоть один
df['a'].isnull().sum()    # сколько NaN

2. Матрица NaN по колонкам

# количество NaN по каждой колонке
df.isnull().sum()

# процент NaN
df.isnull().mean() * 100

# более полная сводка
df.info()

3. dropna — удаление строк с NaN

# удалить строки, где есть хоть один NaN
df.dropna()

# удалить, где ВСЕ значения NaN
df.dropna(how='all')

# удалить только если NaN в конкретной колонке
df.dropna(subset=['a'])

# удалить если больше N NaN в строке
df.dropna(thresh=2)  # оставить строки с минимум 2 не-NaN

# inplace
df.dropna(inplace=True)

4. dropna по колонкам

# удалить колонки, где есть NaN
df.dropna(axis=1)

# удалить колонки, где больше 50% NaN
threshold = len(df) * 0.5
df.dropna(axis=1, thresh=threshold)

5. fillna — заполнение пропусков

# заменить на значение
df['a'].fillna(0)
df['b'].fillna('unknown')

# разные значения для разных колонок
df.fillna({'a': 0, 'b': 'unknown'})

# средним / медианой
df['a'].fillna(df['a'].mean())
df['a'].fillna(df['a'].median())

# модой (наиболее частое)
df['b'].fillna(df['b'].mode()[0])

6. Forward/backward fill

# заполнить предыдущим значением (forward fill)
df.ffill()

# заполнить следующим (backward fill)
df.bfill()

# только N подряд
df['a'].ffill(limit=2)

7. Интерполяция

# линейная интерполяция
df['a'].interpolate()

# другие методы
df['a'].interpolate(method='polynomial', order=2)
df['a'].interpolate(method='time')  # для time series

8. Проверка на NaN в условиях

# фильтр строк без NaN в колонке
df[df['a'].notnull()]

# или с NaN
df[df['a'].isnull()]

# несколько колонок
df[df[['a', 'b']].notnull().all(axis=1)]

# если хоть одна из колонок не NaN
df[df[['a', 'b']].notnull().any(axis=1)]

9. Работа с пустыми строками

Пустая строка "" не равна NaN. Часто нужно преобразовать:

# пустые строки → NaN
df.replace('', np.nan, inplace=True)

# пробельные → NaN
df = df.replace(r'^\s*$', np.nan, regex=True)

10. Work с pd.NA (nullable)

Современный pandas поддерживает nullable integer и string:

df['a'] = df['a'].astype('Int64')  # capital I — nullable int
df['b'] = df['b'].astype('string') # вместо object

# pd.NA универсальный NULL
df.isna()  # работает с pd.NA тоже

11. В Groupby с NaN

По умолчанию NaN не попадают в группы:

df.groupby('category').sum()  # пропустит строки с NaN в category

Чтобы включить:

df.groupby('category', dropna=False).sum()

12. Агрегаты и NaN

По умолчанию игнорируют NaN:

df['a'].sum()    # игнорирует NaN
df['a'].mean()   # среднее по не-NaN

# учесть NaN как 0
df['a'].fillna(0).sum()

# количество не-NaN
df['a'].count()

# количество всех (включая NaN)
len(df['a'])

Разница isnull() / isna() / is_null

  • isnull() и isna() — одно и то же (алиасы)
  • is_null — SQL-термин, в pandas такого нет
  • В новых версиях предпочитают isna()

NaN vs None

import numpy as np

np.nan == np.nan  # False (!)
None == None      # True

# поэтому никогда не пишем `== np.nan`
df['a'] == np.nan  # всегда False

# правильно
df['a'].isna()

Частые ошибки

Ошибка 1. == np.nan

# НЕ работает
df[df['a'] == np.nan]

# правильно
df[df['a'].isna()]

Ошибка 2. dropna без inplace

# не меняет df
df.dropna()
# df остался прежним

# правильно
df = df.dropna()
# или
df.dropna(inplace=True)

Ошибка 3. fillna не применилась на всю колонку

# возвращает новую серию, df не меняется
df['a'].fillna(0)

# правильно
df['a'] = df['a'].fillna(0)

Ошибка 4. Смешивание int и NaN

# pandas автоматически конвертирует в float из-за NaN
df = pd.DataFrame({'a': [1, 2, np.nan]})
df['a'].dtype  # float64

# чтобы сохранить int, используйте nullable:
df['a'] = df['a'].astype('Int64')

Ошибка 5. Drop vs fillna — когда что

  • dropna — если строк с пропусками мало и они не важны
  • fillna — если пропуски имеют смысл (0 для count, mean для числа)
  • interpolate — для временных рядов
  • оставить как есть — если дальше обработает модель

Связанные темы

FAQ

isnull() или isna() — что выбрать?

Любое. Они идентичны. Современный стиль — isna().

Как найти дубликаты и NaN одновременно?

df[df.duplicated() | df.isna().any(axis=1)]

Что делать, если 50% значений NaN?

Зависит от задачи. Если колонка важна → искать причину пропусков или моделировать их. Если нет — dropna по колонке.

NaN в groupby по умолчанию пропускается?

Да. Чтобы включить группу с NaN: groupby(..., dropna=False).


Тренируйте Python и pandas — откройте тренажёр с 1500+ вопросами для собесов.