Python 大型阵列的插值和外推

Python 大型阵列的插值和外推,python,numpy,scipy,interpolation,Python,Numpy,Scipy,Interpolation,我有一个大数组y定义在一个非均匀、有序的网格x上。数组的长度通常为N~2^14到N~2^18。我想得到数组的样条插值(或二次插值)。我面临的问题是,即使对于较低的N值,插值也需要很长时间 import numpy as np from scipy.interpolate import interp1d N = 2 ** 12 # = 4096 x = np.linspace(0, 2*np.pi, N) y = np.sin(x) %time f = interp1d(x, y, 'cubic'

我有一个大数组
y
定义在一个非均匀、有序的网格
x
上。数组的长度通常为N~2^14到N~2^18。我想得到数组的样条插值(或二次插值)。我面临的问题是,即使对于较低的N值,插值也需要很长时间

import numpy as np
from scipy.interpolate import interp1d
N = 2 ** 12 # = 4096
x = np.linspace(0, 2*np.pi, N)
y = np.sin(x)
%time f = interp1d(x, y, 'cubic', )

CPU times: user 8min 5s, sys: 1.39 s, total: 8min 7s
Wall time: 8min 7s
我看到的一个选择是,我只需要在一组非常有限的数据点上使用插值的值。 有没有办法只在要求时计算插值

您能否建议一种替代方法,该方法还可以在
x.min()
以下和
x.max()
以上的值上进行外推


谢谢大家! 现在,您可以使用最小二乘法来近似加权系数,然后以所需的分辨率在任意位置重新采样。如果采用这种方法,还可以基于平滑度对系统进行正则化,以便在x.min()和x.max()之外提供更合理的值

这是配置方法:假设你的样本值在向量x,y中。将基向量设置为phi_k(x)的采样版本

然后设置你的基础B=c_[phi_1,phi_2,…,phi_M],并使用最小二乘法:c,res,rnk,sv=lstsq(B,y)

如果基多项式的数目很小,那么这可能会很快

现在你的向量c,包含coefs。您可以通过构建在感兴趣点采样的新基向量来计算新值:Bnew=c_[phi_1_new,phi_2_new,…,phi_M_new]

投影y_new=点(Bnew,c)

  • 此方法很容易让您控制使用您选择的任何类型的正则化进行增强
  • 并在任意点对系统进行重新采样
  • 使用对您的问题有意义的任何基函数
  • 如果M足够小,则系统可以快速求解

作为@HYRY评论的补充,并支持他使用
插值单变量样条线的建议,以下是我使用一组不同数组长度制作的一些基准测试

interp1d的伸缩性似乎不太好,如下图所示(y轴是每个点的对数时间[大多数负值对应于每个插值点的最快计算],x轴幂为2 in
N

即使在
interp1d
性能最好的地方(接近
N=2**4
2**5
插值单变量样条线的速度也要快2.5个数量级左右。要绘制的代码如下所示

导入matplotlib.pyplot作为plt
将numpy作为np导入
从scipy.interpolate导入interp1d,InterpolateUnivariateSpline
t=[]
对于范围(2,24)内的i:
N=2**i
x=np.linspace(0,2*np.pi,N)
y=np.sin(x)
t_u=time.time()
对于范围(20)内的j:#使结果更稳健
#f=1d(x,y,种类=3)
f=插值单变量样条线(x,y,k=3)
t=time.time()-t_
t、 追加(np.log(t\un/N))
地块(北阿兰奇(22)+2,t)

请注意,
interpolateUnivariateSpline
将为大型输入数组消耗更多内存,因此如果考虑到这一点,
interp1d
可能是更好的选择

插值单变量样条线如何?