如何使用pandas.DataFrame.interpolate插值首尾缺失值?
解决Pandas插值无法处理首尾NaN的问题
我知道这个问题之前有人问过,但找到的方案都不管用。我有一份包含0值的时间序列数据,想用pandas.DataFrame.interpolate对其中的0值做插值处理。
我的代码
import pandas as pd import numpy as np data = [0, -1.31527, -2.25448, -0.965348, -1.11168, -0.0506046, -0.605522, 2.01337, 0, 0, 2.41931, 0.821425, 0.402411, 0] df = pd.DataFrame(data=data) # 转为DataFrame df.replace(to_replace=0, value=np.nan, inplace=True) # 将0替换为NaN ip = df.interpolate(method="nearest", order=3, limit=None, limit_direction=None) print(ip)
运行结果
0 0 NaN 1 -1.315270 2 -2.254480 3 -0.965348 4 -1.111680 5 -0.050605 6 -0.605522 7 2.013370 8 2.013370 9 2.419310 10 2.419310 11 0.821425 12 0.402411 13 NaN
核心问题
问题:Pandas没有对数据首尾的NaN值进行插值,始终保留为NaN。我试过interpolate的forward、backward等所有方向参数,首尾的NaN还是无法被填充。这是Pandas做不到的功能,还是我操作错了?
解决方案
这不是Pandas的功能限制,是你选用的nearest插值方法的特性——它需要依赖相邻的非NaN值来计算填充值,但首尾的NaN没有足够的相邻参考数据(第一个NaN左侧无数据,最后一个NaN右侧无数据),所以单纯靠interpolate的参数无法处理。
可以通过先插值,再补全首尾NaN的方式解决:
方法1:链式填充
# 先插值,再用bfill补开头、ffill补结尾 ip = df.interpolate(method="nearest", order=3).bfill().ffill()
方法2:手动指定首尾值
如果想精准控制首尾的填充值(比如首NaN用第一个非NaN值,尾NaN用最后一个非NaN值),可以直接赋值:
ip = df.interpolate(method="nearest", order=3) # 填充开头NaN ip.iloc[0] = ip.iloc[ip.first_valid_index()] # 填充结尾NaN ip.iloc[-1] = ip.iloc[ip.last_valid_index()]
说明
bfill():用当前NaN之后的第一个非NaN值向前填充,适合处理开头的NaN;ffill():用当前NaN之前的最后一个非NaN值向后填充,适合处理结尾的NaN;- 先执行插值再补全,既保留了中间数据的插值效果,又解决了首尾NaN的问题。
内容的提问来源于stack exchange,提问作者Philipp
相关产品推荐
相关产品推荐

