Pandas df.fillna() 函数
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)
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
代码解析:
- 我们创建了一个包含多个缺失值的 DataFrame。
- 使用
df.fillna(0)将所有缺失值替换为 0。 - 这种方法简单直接,但可能不适用于所有场景,例如年龄和薪资用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)
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)
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)
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)
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)
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 常用函数