【Pandas】pandas DataFrame interpolate
Pandas2.2 DataFrame
Missing data handling
方法 | 描述 |
---|---|
DataFrame.fillna([value, method, axis, …]) | 用于填充 DataFrame 中的缺失值(NaN) |
DataFrame.backfill(*[, axis, inplace, …]) | 用于**使用后向填充(即“下一个有效观测值”)来填补缺失值(NaN)**的方法 |
DataFrame.bfill(*[, axis, inplace, limit, …]) | 用于**使用后向填充(即“下一个有效观测值”)来填补缺失值(NaN)**的方法 |
DataFrame.dropna(*[, axis, how, thresh, …]) | 用于删除包含缺失值(NaN)的行或列的方法 |
DataFrame.ffill(*[, axis, inplace, limit, …]) | 用于**使用前向填充(即“前一个有效观测值”)来填补缺失值(NaN)**的方法 |
DataFrame.interpolate([method, axis, limit, …]) | 用于对缺失值(NaN)进行插值填充的方法 |
pandas.DataFrame.interpolate()
pandas.DataFrame.interpolate()
是一个用于对缺失值(NaN)进行插值填充的方法。它支持多种插值方法,适用于时间序列、传感器数据等需要平滑填补缺失值的场景。
📌 方法签名
DataFrame.interpolate(method='linear', *, axis=0, limit=None, inplace=False, limit_direction=None, limit_area=None, downcast=<no_default>, **kwargs)
🔧 参数说明
参数 | 类型 | 说明 |
---|---|---|
method | str 或 function ,默认 'linear' | 插值方法: - 'linear' :线性插值- 'time' :基于时间索引的插值- 'index' / 'values' :基于索引或值进行插值- 'pad' / 'nearest' / 'polynomial' / 'spline' 等 |
axis | {0/'index', 1/'columns'} ,默认 0 | 插值方向: - 0 :按行插值- 1 :按列插值 |
limit | int ,可选 | 最多连续插值的 NaN 数量;未指定则全部插值 |
inplace | bool ,默认 False | 是否在原对象上修改 |
limit_direction | {'forward', 'backward', 'both'} ,默认 'forward' | 插值方向控制: - 'forward' :从前向后插值- 'backward' :从后向前插值- 'both' :双向插值 |
limit_area | {'inside', 'outside'} ,默认 None | 插值区域控制: - 'inside' :仅填充被非空包围的 NaN- 'outside' :仅填充边缘 NaN |
downcast | dict 或 'infer' ,可选 | 控制是否尝试将结果转换为更小的数据类型 |
**kwargs | 其他参数 | 传递给底层插值函数的额外参数(如 order 用于多项式插值) |
✅ 返回值
- 返回一个新的
DataFrame
,其中的NaN
值被插值; - 如果
inplace=True
,则返回None
,原始数据被修改。
🧪 示例代码及结果
示例 1:基本用法 - 使用线性插值(默认)
import pandas as pd
import numpy as npdf = pd.DataFrame({'A': [1, np.nan, 3, np.nan, 5],'B': [np.nan, 2, np.nan, 4, np.nan]
})print("Original DataFrame:")
print(df)# 使用线性插值
df_interpolated = df.interpolate()
print("\nAfter interpolate():")
print(df_interpolated)
输出结果:
Original DataFrame:A B
0 1.0 NaN
1 NaN 2.0
2 3.0 NaN
3 NaN 4.0
4 5.0 NaNAfter interpolate():A B
0 1.0 NaN
1 2.0 2.0
2 3.0 3.0
3 4.0 4.0
4 5.0 NaN
注意首尾的 NaN 没有被插值,除非使用
limit_direction='both'
。
示例 2:设置 limit_direction='both'
- 双向插值
# 双向插值
df_both = df.interpolate(limit_direction='both')
print("\nAfter interpolate(limit_direction='both'):")
print(df_both)
输出结果:
After interpolate(limit_direction='both'):A B
0 1.0 2.0
1 2.0 2.0
2 3.0 3.0
3 4.0 4.0
4 5.0 NaN
第一行
B
列现在也被插值了(从后往前),但最后一行仍为NaN
(无后续值)。
示例 3:限制最大插值数量(limit=1)
# 设置最多插值 1 个连续 NaN
df_limited = df.interpolate(limit=1)
print("\nAfter interpolate(limit=1):")
print(df_limited)
输出结果:
After interpolate(limit=1):A B
0 1.0 NaN
1 2.0 2.0
2 3.0 NaN
3 NaN 4.0
4 5.0 NaN
每列只插值一个 NaN。
示例 4:使用 method='polynomial'
进行多项式插值
# 多项式插值(需指定 order)
df_poly = df.interpolate(method='polynomial', order=1)
print("\nAfter interpolate(method='polynomial', order=1):")
print(df_poly)
输出结果:
After interpolate(method='polynomial', order=1):A B
0 1.0 NaN
1 2.0 2.0
2 3.0 3.0
3 4.0 4.0
4 5.0 NaN
多项式插值更适合趋势明显的数据,但要求至少有两个有效点。
示例 5:使用 method='time'
(适合时间序列)
# 构造带时间索引的 DataFrame
rng = pd.date_range('2024-01-01', periods=5, freq='D')
df_time = pd.DataFrame({'value': [10, np.nan, np.nan, 40, 50]
}, index=rng)print("Time Series DataFrame:")
print(df_time)# 使用 time 插值
df_time_interpolated = df_time.interpolate(method='time')
print("\nAfter interpolate(method='time'):")
print(df_time_interpolated)
输出结果:
Time Series DataFrame:value
2024-01-01 10.0
2024-01-02 NaN
2024-01-03 NaN
2024-01-04 40.0
2024-01-05 50.0After interpolate(method='time'):value
2024-01-01 10.0
2024-01-02 20.0
2024-01-03 30.0
2024-01-04 40.0
2024-01-05 50.0
时间插值会考虑索引的时间间隔,因此比线性插值更精确。
示例 6:使用 limit_area='inside'
仅插值内部 NaN
# 构造包含边界和内部 NaN 的 DataFrame
df_limit_area = pd.DataFrame({'A': [np.nan, 2, np.nan, 4, np.nan], # 边缘 NaN'B': [1, np.nan, 3, np.nan, 5] # 内部 NaN
})print("Original DataFrame with edge and internal NaNs:")
print(df_limit_area)# 只插值被非空包围的 NaN(不插值边缘)
df_inside = df_limit_area.interpolate(limit_area='inside')
print("\nAfter interpolate(limit_area='inside'):")
print(df_inside)
输出结果:
Original DataFrame with edge and internal NaNs:A B
0 NaN 1.0
1 2.0 NaN
2 NaN 3.0
3 4.0 NaN
4 NaN 5.0After interpolate(limit_area='inside'):A B
0 NaN 1.0
1 2.0 2.0
2 NaN 3.0
3 4.0 4.0
4 NaN 5.0
只填充了中间的 NaN,首尾的未填充。
示例 7:使用 method='pad'
进行前向插值
# 使用 pad 插值(即前向填充)
df_pad = df.interpolate(method='pad')
print("\nAfter interpolate(method='pad'):")
print(df_pad)
输出结果:
After interpolate(method='pad'):A B
0 1.0 NaN
1 1.0 2.0
2 3.0 2.0
3 3.0 4.0
4 5.0 4.0
行为与
ffill()
相似,但可以结合limit
和limit_direction
更灵活控制。
示例 8:原地修改(inplace=True)
# 原地修改
df.interpolate(inplace=True)
print("\nIn-place interpolate (modified original):")
print(df)
输出结果(基于示例 1 的数据):
In-place interpolate (modified original):A B
0 1.0 NaN
1 2.0 2.0
2 3.0 3.0
3 4.0 4.0
4 5.0 NaN
🧠 应用场景
- 时间序列数据处理:填补缺失的时间点数据;
- 传感器或日志数据清洗:保持趋势一致性的插值;
- 数据分析预处理:避免因缺失值影响统计计算;
- 可视化前清理数据:提高图表完整性;
- 模型训练输入准备:生成完整特征矩阵;
- 链式调用中清理数据:如
df.interpolate().fillna(0)
。
⚠️ 注意事项
- 默认使用线性插值(
method='linear'
); - 支持多种插值方式(如
'time'
,'polynomial'
,'spline'
); method='polynomial'
和'spline'
需要scipy
;limit_direction='both'
可以双向插值;limit_area='inside'
/'outside'
控制插值范围;- 不会对整列/整行为 NaN 的情况插值;
- 推荐先排序索引再插值,尤其是时间序列;
- 可以结合
fillna()
使用,作为后备方案; - 仅对
NaN
生效,不会处理None
或其他空值。
✅ 总结对比
插值方法 | 特点 | 适用场景 |
---|---|---|
'linear' | 线性插值 | 通用 |
'time' | 基于时间索引 | 时间序列 |
'pad' / 'ffill' | 前向填充 | 快速简单 |
'bfill' / 'backfill' | 后向填充 | 快速简单 |
'polynomial' | 多项式拟合 | 数据趋势明显 |
'spline' | 样条插值 | 平滑曲线拟合 |
'nearest' | 最近邻插值 | 整数型或离散型数据 |
你可以根据数据特性选择最适合的插值方法,例如:
- 时间序列 →
method='time'
- 趋势明显 →
method='polynomial'
- 快速简单 →
method='pad'
或method='linear'
- 平滑曲线 →
method='spline'
如需更高阶插值,建议安装 scipy
。