Функция Pandas df.fillna()

Pandas 常用函数Pandas: общие функции


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 pandas as pd
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

Пояснение к коду:

  1. Мы создали DataFrame, содержащий множество пропущенных значений.
  2. Используйтеdf.fillna(0)чтобы заменить все пропущенные значения на 0.
  3. Этот метод прост и прямолинеен, но может подходить не для всех сценариев; например, заполнение возраста и зарплаты значением 0 может быть неразумным.

Пример 2: Указание разных значений заполнения для разных столбцов с помощью словаря

Вы можете указать разные значения заполнения для разных столбцов, чтобы сделать данные более разумными.

Пример

import pandas as pd
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 pandas as pd
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 pandas as pd
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 pandas as pd
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 pandas as pd
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 常用函数Pandas: общие функции

Другие расширения