Коротко
- Пропуск в числах и строках —
NaN; в nullable-типах (Int64,boolean,string) —pd.NA.Noneпри создании превращается в одно из них. isna()/notna()— маски;isna().sum()— сколько пропусков в каждом столбце.fillna(значение)— заполнить; словарь — своё значение для каждого столбца.ffill()/bfill()— предыдущим / следующим значением.dropna()удаляет строки с пропусками;subset— смотреть только на эти столбцы,thresh— сколько непустых значений нужно, чтобы оставить строку.interpolate()— восстановить значения между известными (линейно, по времени и т. д.).
Синтаксис
df.isna(), df.notna(), df.isna().sum()
df.fillna(value) # число или {"col": value}
df.ffill(), df.bfill()
df.dropna(how="any", subset=None, thresh=None, axis=0)
s.interpolate(method="linear")Параметры
ПараметрЧто делаетПо умолчанию
valueв fillna: значение, словарь по столбцам или Seriesобязательныйhowв dropna: "any" — удалить при любом пропуске, "all" — только если пропущено всё"any"subsetв dropna: какие столбцы проверятьвсеthreshв dropna: минимальное число непустых значений в строкеNoneaxis0 — строки, 1 — столбцы (в ffill — заполнять вдоль строки)0limitв fillna / ffill / interpolate: сколько подряд пропусков заполнятьNonemethodв interpolate: "linear", "time", "nearest", "polynomial"…"linear"Примеры
temps = pd.DataFrame({
"city": ["Омск", "Тула", "Сочи", None],
"mon": [12.0, None, 21.0, 8.0],
"tue": [None, None, 22.5, 9.5],
})print(temps.isna())
temps.isna().sum() # пропуски по столбцамВывод
city mon tue 0 False False True 1 False True True 2 False False False 3 True False False city 1 mon 1 tue 2 dtype: int64
print(temps.fillna({"city": "?", "mon": 0})) # по столбцам
temps["mon"].fillna(temps["mon"].mean()) # среднимВывод
city mon tue 0 Омск 12.0 NaN 1 Тула 0.0 NaN 2 Сочи 21.0 22.5 3 ? 8.0 9.5 0 12.000000 1 13.666667 2 21.000000 3 8.000000 Name: mon, dtype: float64
temps[["mon", "tue"]].ffill(axis=1) # предыдущим значением в строкеВывод
mon tue 0 12.0 12.0 1 NaN NaN 2 21.0 22.5 3 8.0 9.5
print(temps.dropna()) # строки без единого пропуска
print(temps.dropna(subset=["city"])) # пропуск только в city
temps.dropna(thresh=2) # хотя бы 2 непустых значенияВывод
city mon tue 2 Сочи 21.0 22.5 city mon tue 0 Омск 12.0 NaN 1 Тула NaN NaN 2 Сочи 21.0 22.5 city mon tue 0 Омск 12.0 NaN 2 Сочи 21.0 22.5 3 NaN 8.0 9.5
s = pd.Series([10.0, None, None, 16.0, None, 20.0])
s.interpolate() # линейно между соседямиВывод
0 10.0 1 12.0 2 14.0 3 16.0 4 18.0 5 20.0 dtype: float64
print(pd.Series([1, None]).dtype) # число + None → float64 с NaN
print(pd.Series(["a", None]).dtype) # строка + None → str с NaN
pd.Series([1, None], dtype="Int64") # целые с пропуском — pd.NAВывод
float64 str 0 1 1 <NA> dtype: Int64
Подводные камни
Сравнение с np.nan
temps["mon"] == np.nan # так пропуски не найтиВывод
0 False 1 False 2 False 3 False Name: mon, dtype: bool
Проверяйте пропуски только через isna().
fillna(method=…) удалён
temps["mon"].fillna(method="ffill")Ошибка
TypeError: NDFrame.fillna() got an unexpected keyword argument 'method'