如何用pandas/scipy实现按行单值线性插值?
按行对应指定x值的线性插值需求
数据与需求说明
现有如下Pandas DataFrame,其中列名作为插值的x数组,每行的数值对应x数组的y值:
import pandas as pd df = pd.DataFrame([[-10, -5, 0, 10], [17, 10, 16, 20], [40, 30, 10, -6]], columns=[0, 10, 20, 30]) # 查看数据结构 >>> df.values array([[-10, -5, 0, 10], [ 17, 10, 16, 20], [ 40, 30, 10, -6]]) >>> df.columns Int64Index([0, 10, 20, 30], dtype='int64')
需要对每行执行线性插值,且每行对应一个指定的新x值:
new_x = [5, 15, 25]
即:
- 第一行用列名x数组、行内y值插值
5 - 第二行插值
15 - 第三行插值
25
预期结果为:[-7.5, 13., 2.]
尝试的代码与问题
使用scipy.interpolate.interp1d直接插值时,会得到每行对所有new_x元素的插值结果:
from scipy import interpolate interp_result = interpolate.interp1d(x=df.columns, y=df)(new_x) >>> interp_result array([[-7.5, -2.5, 5. ], [13.5, 13. , 18. ], [35. , 20. , 2. ]])
该结果是一个二维数组,我们仅需要其中的对角线元素,希望找到更自然高效的单行写法。
高效单行解决方案
方法1:提取插值结果的对角线(最简洁)
直接利用numpy.diag提取二维插值结果的对角线元素,这是最符合需求的单行写法:
import numpy as np from scipy import interpolate result = np.diag(interpolate.interp1d(x=df.columns, y=df)(new_x)) >>> result array([-7.5, 13. , 2. ])
方法2:逐行匹配插值(内存更高效)
如果数据集较大,不想生成完整的二维插值数组,可以用生成器表达式结合np.array转换,直接计算每行对应new_x值的插值:
result = np.array([interpolate.interp1d(df.columns, row)(nx) for row, nx in zip(df.values, new_x)]) >>> result array([-7.5, 13. , 2. ])
说明
- 方法1利用
interp1d的批量计算特性,先得到所有插值结果再提取对角线,写法简洁,适合中小数据集; - 方法2逐行计算对应x值的插值,避免生成冗余的中间数组,内存效率更高,适合大数据集。
内容的提问来源于stack exchange,提问作者Mark.R
相关产品推荐
相关产品推荐

