如果我想要空插值(分段常数),numpy.interp的最佳直接替换是什么?

时间:2012-09-02 23:41:58

标签: python numpy interpolation

numpy.interp非常方便且相对较快。在某些情况下,我想将其输出与稀疏值传播的非插值变量(在“密集”输出中)进行比较,结果在稀疏输入之间是分段常数。我想要的功能也可以称为“稀疏 - >密集”转换器,它复制最新的稀疏值,直到找到更晚的值(一种空插值,好像零时间/距离从早期值开始经过)。

不幸的是,调整numpy.interp的源代码并不容易,因为它只是编译函数的包装器。我可以使用Python循环自己编写,但希望找到一种C-speed方法来解决问题。

更新:下面的解决方案(scipy.interpolate.interp1dkind='zero')相当缓慢,每次通话需要10秒以上(例如输入500k,填充50%) 。它使用零阶样条实现kind='zero',对spleval的调用非常慢。但是,kind='linear'的源代码(即默认插值)为使用直接numpy解决问题提供了一个很好的模板(最小的更改是设置slope=0)。该代码显示了如何使用numpy.searchsorted来解决问题,运行时类似于调用numpy.interp,因此通过调整线性插值的scipy.interpolate.interp1d实现来跳过插值步骤可以解决问题(斜率!= 0混合相邻的值)。

3 个答案:

答案 0 :(得分:3)

scipy.interpolate.interp1d可以进行各种插值:'线性','最近','零','线性','二次','立方'。

请查看文档:{​​{3}}

答案 1 :(得分:0)

刚刚完成:问题的解决方案是以下代码,我可以借助更新后的答案中提供的提示编写:

def interpolate_constant(x, xp, yp):
    indices = np.searchsorted(xp, x, side='right')
    y = np.concatenate(([0], yp))
    return y[indices]

答案 2 :(得分:0)

我完全同意那种='零'非常慢;对于一百万行的大数据集,它可以比“线性”方法慢1000倍。对于“左 - 常数”插值 - 使用最新值 - 以下代码有效:

def approx(x, y, xout, yleft=np.nan, yright=np.nan): 
    xoutIdx     = np.searchsorted(x, xout, side='right')-1
    return (np.where(xout<x[0], yleft, np.where(xout>x[-1], yright, y[xoutIdx])))

来自R背景,这相当于R的近似值f = 0。我还没有找到一种干净的方法来进行“右 - 常”插值,因为如果xout值与x中的值完全匹配,python的带有side ='right'的np.searchsorted会将一个索引推回...