Pandas重采样插值返回全NaN问题的原因及解决方法咨询
Pandas重采样插值返回全NaN问题的原因及解决方法咨询
嗨,我来帮你拆解这个问题,先看看你的代码和遇到的现象:
import pandas as pd data = { "Date": ["2016-01", "2017-01", "2018-01"], "In Vitro Diagnostics": [10, 15, 20] } df = pd.DataFrame(data) # Convert the 'Date' column to datetime format df['Date'] = pd.to_datetime(df['Date'], format='%Y-%m') # Setting 'Date' as the index df.set_index('Date', inplace=True) # Resampling the data to monthly frequency and interpolating the values df = df.resample('M').interpolate() # df = df.resample('M').ffill() # works # Converting the DateTimeIndex to PeriodIndex df.index = df.index.to_period('M') print(df)
你发现用resample('M').interpolate()得到的结果全是NaN,但ffill()却能正常填充,想知道原因和解决办法,对吧?
问题原因分析
核心问题出在resample和interpolate的组合逻辑上:
- 当你直接调用
df.resample('M').interpolate()时,Pandas会把interpolate当作重采样的聚合函数,尝试在每个重采样的“月份组”内进行插值。但你的原始数据只有每年1月有值,每个月份组要么只有一个数据点,要么完全没有数据,单个数据点无法完成线性插值计算,所以最终返回全NaN。 - 而
ffill()是向前填充逻辑,它会把最近的非NaN值直接填充到后续所有空值的月份组里,所以能正常得到结果。
解决方法
要实现年度数据到月度数据的线性插值,你需要先通过asfreq()生成完整的月度时间序列(空值用NaN填充),再对这个完整序列进行插值。修改后的代码如下:
import pandas as pd data = { "Date": ["2016-01", "2017-01", "2018-01"], "In Vitro Diagnostics": [10, 15, 20] } df = pd.DataFrame(data) # Convert the 'Date' column to datetime format df['Date'] = pd.to_datetime(df['Date'], format='%Y-%m') # Setting 'Date' as the index df.set_index('Date', inplace=True) # 先生成完整月度序列,再执行线性插值 df = df.resample('M').asfreq().interpolate(method='linear') # Converting the DateTimeIndex to PeriodIndex df.index = df.index.to_period('M') print(df)
补充说明
resample('M').asfreq()会生成从第一个日期到最后一个日期的所有月份索引,原始数据存在的月份保留原值,其他月份填充NaN,相当于搭好了完整的时间框架。- 调用
interpolate(method='linear')后,Pandas会沿着时间轴对连续的NaN进行线性插值,这样就能得到10到15、15到20之间的月度递增数据。 - 如果想让插值更贴合实际时间间隔(比如考虑不同月份的天数差异),可以把插值方法改成
method='time',它会根据时间差进行加权插值:df = df.resample('M').asfreq().interpolate(method='time')
备注:内容来源于stack exchange,提问作者aushdk
相关产品推荐
相关产品推荐

