现在位置: 首页 > Pandas 教程 > 正文

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)

参数说明

参数 类型 是否必填 说明 默认值
value scalar, dict, Series, DataFrame 可选 用于填充缺失值的值。可以是一个常数、字典(指定不同列的不同值)、Series 或 DataFrame。 None
method str 可选 填充方法。'ffill''pad' 表示用前一个值填充(向前填充);'bfill''backfill' 表示用后一个值填充(向后填充)。 None
axis int 或 str 可选 指定填充方向。0'index' 表示按行填充;1'columns' 表示按列填充。仅在 method 不为 None 时有效。 0
inplace bool 可选 如果为 True,直接在原 DataFrame 上修改,不返回新对象;如果为 False,返回一个新的 DataFrame,原数据不变。 False
limit int 可选 指定连续填充的最大数量。例如设置 limit=1 表示每次只填充1个缺失值。 None
downcast dict 或 str 可选 指定数据类型向下转换的规则,如将 float64 转换为 int64。 None

返回值说明

  • 返回一个新的 DataFrame(如果 inplace=False),或者 None(如果 inplace=True)。
  • 返回的 DataFrame 中缺失值已被填充。

实例

让我们通过一系列例子,彻底掌握 fillna() 的用法。

示例 1:用常数填充所有缺失值

最简单的用法是用一个常数填充所有缺失值。

实例

import pandas as pd
import numpy as np

# 创建一个包含缺失值的 DataFrame
data = {
    '姓名': ['张三', '李四', '王五', '赵六'],
    '年龄': [25, np.nan, 35, np.nan],  # 缺失值
    '薪资': [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 = {
    '姓名': ['张三', '李四', '王五', '赵六'],
    '年龄': [25, np.nan, 35, np.nan],
    '薪资': [5000, 6000, np.nan, 8000],
    '部门': ['技术', '市场', '技术', np.nan],
    '绩效': [85, 90, np.nan, 95]
}
df = pd.DataFrame(data)

print("原始数据:")
print(df)
print("=" * 50)

# 用字典为不同列指定不同的填充值
fill_values = {
    '年龄': 30,  # 年龄缺失用30填充
    '薪资': 6500,  # 薪资缺失用6500填充
    '部门': '未分配',  # 部门缺失用"未分配"填充
    '绩效': 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 = {
    '姓名': ['张三', '李四', '王五', '赵六', '钱七'],
    '数学': [85, 90, np.nan, 78, 92],
    '英语': [88, np.nan, 82, 85, 90],
    '物理': [np.nan, 85, 90, 88, 95]
}
df = pd.DataFrame(data)

print("原始数据:")
print(df)
print("=" * 50)

# 计算每列的均值
math_mean = df['数学'].mean()
english_mean = df['英语'].mean()
physics_mean = df['物理'].mean()

print(f"数学均值: {math_mean:.2f}")
print(f"英语均值: {english_mean:.2f}")
print(f"物理均值: {physics_mean:.2f}")
print("=" * 50)

# 用均值填充
df_filled = df.fillna({
    '数学': math_mean,
    '英语': english_mean,
    '物理': 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 = {
    '日期': ['2024-01-01', '2024-01-02', '2024-01-03', '2024-01-04', '2024-01-05'],
    '温度': [20, np.nan, 22, np.nan, 25],
    '湿度': [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行的温度缺失,用第0行的20填充;第3行的温度缺失,用第2行的22填充。
  • 向后填充(bfill):第1行的温度缺失,用第2行的22填充;第3行的温度缺失,用第4行的25填充。
  • 这种方法适用于时间序列数据,如股票价格、温度记录等。

示例 5:使用 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() 方法代替。
  • 使用均值填充时,如果数据中存在极端值( outliers),可以考虑使用中位数填充,这样更稳健。
  • 对于分类数据(如部门、职位),建议使用最频繁出现的值(众数)或一个明确的类别(如"未知")来填充。
  • 填充缺失值之前,建议先分析缺失的原因和模式,选择最合适的填充方法。

Pandas 常用函数 Pandas 常用函数