Данные редко бывают идеальными. Часто встречаются пропуски или отсутствующие значения, которые могут искажать анализ. Pandas предоставляет мощные инструменты для работы с такими данными.
Для начала создадим тестовый DataFrame с пропусками:
import pandas as pd
import numpy as np
data = {
'Age': [25, 32, np.nan, 45, 28, np.nan, 35],
'Salary': [50000, 54000, 52000, np.nan, 58000, np.nan, 61000],
'City': ['NY', 'LA', None, 'SF', 'TX', 'NV', 'WA']
}
df = pd.DataFrame(data)
Чтобы определить, где у нас пропущенные значения, используем isna()
или isnull()
.
print(df.isna())
# Age Salary City
# 0 False False False
# 1 False False False
# 2 True False True
# 3 False True False
# 4 False False False
# 5 True True False
# 6 False False False
Чтобы определить количество пропусков в каждом столбце:
print(df.isna().sum())
# Age 2
# Salary 2
# City 1
# dtype: int64
Если количество пропусков невелико, строки с ними можно удалить:
df_cleaned = df.dropna()
Удалить столбцы:
df_cleaned_columns = df.dropna(axis=1)
Замена всех пропусков конкретным значением:
df_filled = df.fillna(0)
Заполнение средним значением по столбцу:
df['Age'].fillna(df['Age'].mean(), inplace=True)
Заполнение медианой:
df['Salary'].fillna(df['Salary'].median(), inplace=True)
Использование метода ffill
(forward fill) для заполнения предыдущим значением:
df['City'].fillna(method='ffill', inplace=True)
Еще один метод — интерполяция, особенно полезна для временных рядов:
df['Age'].interpolate(method='linear', inplace=True)
Применение метода bfill
(backward fill)
Также, как и метод ffill
, который заполняет пропуски предыдущим значением, bfill
заполняет пропуски последующим значением:
df['City'].fillna(method='bfill', inplace=True)
Если у вас есть категориальные данные, вы можете заполнить пропуски наиболее часто встречающейся категорией:
most_common = df['City'].mode()[0]
df['City'].fillna(most_common, inplace=True)
Если в данных есть группы, вы можете заполнять пропуски в зависимости от группы. Например, заполнение медианой зарплаты в зависимости от города:
df['Salary'] = df.groupby('City')['Salary'].transform(lambda x: x.fillna(x.median()))
После всех преобразований убедитесь, что пропусков нет:
assert df.notna().all().all(), "There are still missing values!"
Работа с пропусками — ключевой этап в предварительной обработке данных. Неверное или непродуманное их заполнение может исказить результаты анализа. Всегда стоит задаваться вопросом о причинах возникновения пропусков и выбирать методы их обработки в зависимости от контекста данных.
Содержание: