Функция Pandas df.fillna()
df.fillna()является функцией в Pandas, используемой для заполнения пропущенных значений.
иdropna()В отличие от удаления пропущенных значений,fillna()она позволяет заполнять пропущенные данные заданными значениями, средним, медианой, заполнением вперёд или назад и т. д. Это очень полезно для поддержания целостности данных и точности анализа.
Базовый синтаксис и параметры
fillna()является функцией-членом DataFrame, вызываемой через оператор точка.для вызова.
Формат синтаксиса
DataFrame.fillna(value=None, method=None, axis=None, inplace=False, limit=None, downcast=None)
Описание параметра
| Параметр | Type | Обязательный | Описание | Значение по умолчанию |
|---|---|---|---|---|
| value | скаляр, dict, Series, DataFrame | Optional | Значение, используемое для заполнения пропущенных значений. Это может быть константа, словарь (задающий разные значения для разных столбцов), Series или DataFrame. | Отсутствует |
| method | str | Optional | Метод заполнения.'ffill'или'pad'Указывает на заполнение предыдущим значением (прямое заполнение);'bfill'или'backfill'Указывает на заполнение следующим значением (обратное заполнение). |
Отсутствует |
| axis | int или str | Optional | Задаёт направление заполнения.0или'index'Указывает на заполнение по строкам;1или'columns'Указывает на заполнение по столбцам. Только когдаmethodнеNoneэто допустимо. |
0 |
| inplace | bool | Optional | ЕслиTrue, он напрямую изменяет исходный DataFrame и не возвращает новый объект; еслиFalse, он возвращает новый DataFrame, а исходные данные остаются неизменными. |
False |
| limit | int | Optional | Задаёт максимальное количество последовательных заполнений. Например, установкаlimit=1означает заполнение только 1 пропущенного значения за раз. |
Отсутствует |
| downcast | dict или str | Optional | Задаёт правила понижающего приведения типов данных, например преобразование float64 в int64. | Отсутствует |
Описание возвращаемого значения
- Возвращает новый DataFrame (если
inplace=False), илиNone(еслиinplace=True)。 - В возвращённом DataFrame пропущенные значения заполнены.
Примеры
Давайте с помощью серии примеров досконально освоимfillna()использование df.fillna().
Пример 1: Заполнить все пропущенные значения константой
Простейший вариант использования — заполнить все пропущенные значения константой.
Пример
import numpy as np
# Создать DataFrame, содержащий пропущенные значения
data = {
'Имя': ['Чжан Сань', 'Ли Сы', 'Ван У', 'Чжао Лю'],
'Age': [25, np.nan, 35, np.nan], # пропущенное значение
'Salary': [5000, 6000, np.nan, 8000], # пропущенное значение
'Отдел': ['Технологии', 'Маркетинг', 'Технологии', np.nan] # пропущенное значение
}
df = pd.DataFrame(data)
print("Исходные данные:")
print(df)
print("=" * 50)
# Заполнить все пропущенные значения константой 0
df_filled = df.fillna(0)
print("Данные после заполнения 0:")
print(df_filled)
Ожидаемый вывод:
原始数据:
姓名 年龄 薪资 部门
0 张三 25.0 5000.0 技术
1 李四 NaN 6000.0 市场
2 王五 35.0 NaN 技术
3 赵六 NaN 8000.0 NaN
==================================================
用0填充后的数据:
名称 年龄 薪资 部门
0 张三 25.0 5000.0 技术
1 李四 0.0 6000.0 市场
2 王五 35.0 0.0 技术
3 赵六 0.0 8000.0 0
Пояснение к коду:
- Мы создали DataFrame, содержащий множество пропущенных значений.
- Используйте
df.fillna(0)чтобы заменить все пропущенные значения на 0. - Этот метод прост и прямолинеен, но может подходить не для всех сценариев; например, заполнение возраста и зарплаты значением 0 может быть неразумным.
Пример 2: Указание разных значений заполнения для разных столбцов с помощью словаря
Вы можете указать разные значения заполнения для разных столбцов, чтобы сделать данные более разумными.
Пример
import numpy as np
# Создать DataFrame, содержащий пропущенные значения
data = {
'Имя': ['Чжан Сань', 'Ли Сы', 'Ван У', 'Чжао Лю'],
'Age': [25, np.nan, 35, np.nan],
'Salary': [5000, 6000, np.nan, 8000],
'Отдел': ['Технологии', 'Маркетинг', 'Технологии', np.nan],
'Performance': [85, 90, np.nan, 95]
}
df = pd.DataFrame(data)
print("Исходные данные:")
print(df)
print("=" * 50)
# Использовать словарь для указания разных значений заполнения для разных столбцов
fill_values = {
'Age': 30, # Заполнить пропущенные значения возраста значением 30
'Salary': 6500, # Заполнить пропущенные зарплаты значением 6500
'Department': 'Unassigned', # Заполнить пропущенные отделы значением "Unassigned"
'Performance': 80 # Заполнить пропущенные значения производительности значением 80
}
df_filled = df.fillna(fill_values)
print("Данные после заполнения разных столбцов разными значениями:")
print(df_filled)
Ожидаемый вывод:
原始数据:
姓名 年龄 薪资 部门 绩效
0 张三 25.0 5000.0 技术 85
1 李四 NaN 6000.0 市场 90
2 王五 35.0 NaN 技术 NaN
3 赵六 NaN 8000.0 NaN 95
==================================================
不同列用不同值填充后的数据:
姓名 年龄 薪资 部门 绩效
0 张三 25.0 5000.0 技术 85
1 李四 30.0 6000.0 市场 90
2 王五 35.0 6500.0 技术 80
3 赵六 30.0 8000.0 未分配 95
Пояснение к коду:
- Используя словарь
fill_values, мы указали разумные значения заполнения для каждого столбца. - Этот метод более гибкий и позволяет задавать подходящие значения по умолчанию для разных полей на основе бизнес-логики.
Пример 3: Заполнение числовых столбцов средним или медианой
Для числовых данных заполнение средним или медианой — распространённый и разумный метод.
Пример
import numpy as np
# Создать DataFrame, содержащий пропущенные значения
data = {
'Имя': ['Чжан Сань', 'Ли Сы', 'Ван У', 'Zhao Liu', 'Qian Qi'],
'Math': [85, 90, np.nan, 78, 92],
'English': [88, np.nan, 82, 85, 90],
'Physics': [np.nan, 85, 90, 88, 95]
}
df = pd.DataFrame(data)
print("Исходные данные:")
print(df)
print("=" * 50)
# Вычислить среднее значение каждого столбца
math_mean = df['Math'].mean()
english_mean = df['English'].mean()
physics_mean = df['Physics'].mean()
print(f"Среднее по математике: {math_mean:.2f}")
print(f"Среднее по английскому: {english_mean:.2f}")
print(f"Среднее по физике: {physics_mean:.2f}")
print("=" * 50)
# Заполнить средним значением
df_filled = df.fillna({
'Math': math_mean,
'English': english_mean,
'Physics': physics_mean
})
print("Данные после заполнения средним:")
print(df_filled)
Ожидаемый вывод:
原始数据:
姓名 数学 英语 物理
0 张三 85.0 88.0 NaN
1 李四 90.0 NaN 85.0
2 王五 NaN 82.0 90.0
3 赵六 78.0 85.0 88.0
4 钱七 92.0 90.0 95.0
==================================================
数学均值: 86.25
英语均值: 86.25
物理均值: 89.50
==================================================
用均值填充后的数据:
姓名 数学 英语 物理
0 张三 85.0 88.0 89.5
1 李四 90.0 86.25 85.0
2 王五 86.25 82.0 90.0
3 赵六 78.0 85.0 88.0
4 钱七 92.0 90.0 95.0
Пояснение к коду:
- Используйте
df['列名'].mean()для вычисления среднего значения каждого столбца. - Использование вычисленного среднего в качестве значения для заполнения сохраняет общие характеристики распределения данных, одновременно решая проблему пропущенных значений.
Пример 4: использование прямого заполнения (ffill) и обратного заполнения (bfill)
Прямое заполнение заполняет пропущенные значения предыдущим допустимым значением, а обратное заполнение — следующим допустимым значением.
Пример
import numpy as np
# Создать DataFrame, содержащий пропущенные значения
data = {
'Date': ['2024-01-01', '2024-01-02', '2024-01-03', '2024-01-04', '2024-01-05'],
'Temperature': [20, np.nan, 22, np.nan, 25],
'Humidity': [60, 65, np.nan, 70, 75]
}
df = pd.DataFrame(data)
print("Исходные данные:")
print(df)
print("=" * 50)
# Прямое заполнение: заполнить пропущенные значения предыдущим значением
df_ffill = df.fillna(method='ffill')
print("Данные после прямого заполнения (ffill):")
print(df_ffill)
print("=" * 50)
# Обратное заполнение: заполнить пропущенные значения следующим значением
df_bfill = df.fillna(method='bfill')
print("Данные после обратного заполнения (bfill):")
print(df_bfill)
Ожидаемый вывод:
原始数据:
日期 温度 湿度
0 2024-01-01 20.0 60.0
1 2024-01-02 NaN 65.0
2 2024-01-03 22.0 NaN
3 2024-01-04 NaN 70.0
4 2024-01-05 25.0 75.0
==================================================
向前填充(ffill)后的数据:
日期 温度 湿度
0 2024-01-01 20.0 60.0
1 2024-01-02 20.0 65.0 # 用前一个值20填充
2 2024-01-03 22.0 65.0 # 用前一个值65填充
3 2024-01-04 22.0 70.0 # 用前一个值22填充
4 2024-01-05 25.0 75.0
==================================================
向后填充(bfill)后的数据:
日期 温度 湿度
0 2024-01-01 20.0 60.0
1 2024-01-02 22.0 65.0 # 用后一个值22填充
2 2024-01-03 22.0 70.0 # 用后一个值70填充
填充
3 2024-01-04 25.0 70.0 # 用后一个值25填充
4 2024-01-05 25.0 75.0
Пояснение к коду:
- Прямое заполнение (
ffill): температура в строке 1 отсутствует, заполните её значением 20 из строки 0; температура в строке 3 отсутствует, заполните её значением 22 из строки 2. - Обратное заполнение (
bfill): температура в строке 1 отсутствует, заполните её значением 22 из строки 2; температура в строке 3 отсутствует, заполните её значением 25 из строки 4. - Этот метод подходит для данных временных рядов, таких как цены акций, записи температуры и т. д.
Пример 5: Использование параметра limit для ограничения количества заполнений
limitПараметр limit может ограничивать максимальное количество последовательных заполнений.
Пример
import numpy as np
# Создать DataFrame, содержащий несколько последовательных пропущенных значений
data = {
'A': [1, np.nan, np.nan, np.nan, 5],
'B': [1, 2, np.nan, np.nan, 5]
}
df = pd.DataFrame(data)
print("Исходные данные:")
print(df)
print("=" * 50)
# Прямое заполнение, но с ограничением заполнения только 1 подряд идущего пропущенного значения за раз
df_filled = df.fillna(method='ffill', limit=1)
print(Данные после ограничения количества последовательных заполнений до 1:)
print(df_filled)
Ожидаемый вывод:
原始数据:
A B
0 1.0 1.0
1 NaN 2.0
2 NaN NaN
3 NaN NaN
4 5.0 5.0
==================================================
限制连续填充数量为1后的数据:
A B
0 1.0 1.0
1 1.0 2.0 # 填充1个
2 NaN 2.0 # 达到limit,不再填充
3 NaN NaN # 继续不填充
4 5.0 5.0
Пояснение к коду:
- Для столбца A пропущенное значение в строке 1 заполняется значением 1, но строки 2 и 3 больше не заполняются, так как достигнут limit=1.
- Для столбца B пропущенное значение в строке 2 заполняется значением 2, а строка 3 больше не заполняется, так как достигнут limit=1.
Пример 6: Заполнение пропущенных значений с помощью интерполяции
Pandas также предоставляетinterpolate()метод для заполнения интерполяцией, подходящий для числовых данных.
Пример
import numpy as np
# Создать DataFrame, содержащий пропущенные значения
data = {
'x': [1, 2, 3, 4, 5],
'y': [10, np.nan, 30, np.nan, 50]
}
df = pd.DataFrame(data)
print(Исходные данные:)
print(df)
print("=" * 50)
# Использовать линейную интерполяцию для заполнения
df_interpolated = df.copy()
df_interpolated['y'] = df_interpolated['y'].interpolate(method='linear')
print(Данные после заполнения линейной интерполяцией:)
print(df_interpolated)
Ожидаемый вывод:
原始数据: x y 0 1 10.0 1 2 NaN 2 3 30.0 3 4 NaN 4 5 50.0 ================================================== 线性插值填充后的数据: x y 0 1 10.0 1 2 20.0 # 插值:10 + (30-10)/(3-1)*(2-1) = 20 2 3 30.0 3 4 40.0 # 插值:30 + (50-30)/(5-3)*(4-3) = 40 4 5 50.0
Пояснение к коду:
- Линейная интерполяция вычисляет пропущенные значения на основе известных значений до и после.
- Строка 1: 10 + (30-10)/(3-1)*(2-1) = 20.
- Строка 3: 30 + (50-30)/(5-3)*(4-3) = 40.
- Метод интерполяции подходит для данных, где значения изменяются линейно.
Примечания
fillna()По умолчанию исходный DataFrame не изменяется. Если вы хотите изменить его на месте, используйтеinplace=Trueпараметра.- Примечание
methodЭтот параметр может быть устаревшим в будущих версиях Pandas. Рекомендуется использоватьffill()иbfill()метод вместо него. - При использовании заполнения средним, если в данных есть экстремальные значения (выбросы), рассмотрите использование заполнения медианой, которое более устойчиво.
- Для категориальных данных (таких как отдел, должность) рекомендуется заполнять наиболее частым значением (модой) или явной категорией (например, "Unknown").
- Перед заполнением пропущенных значений рекомендуется сначала проанализировать причины и закономерности пропусков и выбрать наиболее подходящий метод заполнения.
Другие расширения
Pandas: общие функции