pandas按行对DataFrame执行spline插值报索引错误求解
问题描述
现有如下结构的DataFrame:
OBJECTID 2017 2018 2019 2020 2021 1.0 NaN NaN 7569.183179 7738.162829 7907.142480 2.0 NaN NaN 766.591146 783.861122 801.131099 3.0 NaN NaN 8492.215747 8686.747704 8881.279662 4.0 NaN NaN 40760.327825 41196.877473 41633.427120 5.0 NaN NaN 6741.819674 6788.981231 6836.142788
需要对每一行做样条(spline)插值,补全2017、2018年的缺失值,初始尝试代码如下:
years = list(range(2017,2022)) df[years] = df[years].interpolate(method="spline", order =1, limit_direction="both", axis=1)
运行后抛出错误:
ValueError: Index column must be numeric or datetime type when using spline method other than linear. Try setting a numeric or datetime index column before interpolating.
现有公开示例大多为沿列方向的spline插值,无法实现按行插值的需求。
报错原因
当指定axis=1按行做插值时,pandas会将列名作为插值计算的索引轴,spline插值要求该索引必须为数值或datetime类型。多数情况下读入数据时年份列名会被解析为字符串类型,不满足spline插值的类型要求,因此抛出错误。
解决方法
不需要修改原DataFrame的列名结构,也不需要逐行apply运算(效率极低,不适合大规模数据集),通过转置将行方向插值转换为更常用的列方向插值即可,代码如下:
import pandas as pd years = list(range(2017, 2022)) # 提取年份列并转置,此时原行变为列,原列名(年份)变为行索引 temp_df = df[years].T # 将行索引(年份)转为数值类型,满足spline插值要求 temp_df.index = pd.to_numeric(temp_df.index) # 沿默认的axis=0(列方向)做样条插值,等价于原表的行方向插值 temp_df = temp_df.interpolate(method="spline", order=1, limit_direction="both") # 插值完成后转置回原结构,赋值回原DataFrame df[years] = temp_df.T
运行后即可得到补全2017、2018年缺失值的结果,以第一行为例,插值后2017年值为7231.22、2018年值为7400.20,符合线性样条的趋势推算结果。如果需要使用更高阶的样条插值,仅需修改order参数即可,逻辑完全一致。
内容的提问来源于stack exchange,提问作者ACAYA
相关产品推荐
相关产品推荐

