我有关于scipy的splrep函数的问题,我认为这是一个错误,因此我会发布每一段代码,以便您可以在计算机上重现它。假设我想找到一些数据的b样条表示,比如,通过以下代码获得的数据,它创建了一个数据集,它是十个高斯的混合,带有一些加法噪声:
import numpy as np
# First we define the number of datapoints:
ndata = 100
x = np.arange(0,1,1./np.double(ndata))
means = np.random.uniform(0,1,10)
y = 0.0
for i in range(len(means)):
y = y+np.exp(-(x-means[i])**2./0.01)
# We add some noise to obtain the data:
data = y + np.random.normal(0,0.05,len(y))
哪个应该是这样的: 现在,让我们使用splrep和splev函数来获得该曲线的b样条表示:
from scipy.interpolate import splrep,splev
# First define the number of knots. Let's put, say, 10 knots:
nknots = 10
# Now we crate the array of knots:
knots = np.arange(x[1],x[len(x)-1],(x[len(x)-1]-x[1])/np.double(nknots))
tck = splrep(x,data,t=knots)
fit = splev(x,tck)
如果您将所有内容绘制到此处,一切似乎都可以:
但是,数据点数和结数的某些组合存在问题。例如,如果您使用ndata = 1931
和nknots = 796
尝试上述代码,则会收到以下错误:
File "/usr/lib/python2.7/dist-packages/scipy/interpolate/fitpack.py", line 465, in
splrep raise _iermess[ier][1](_iermess[ier][0])
ValueError: Error on input data
这给我带来了问题,因为上面的代码不能自动化。我正在使用具有~19000个数据点的数据集,其中while
周期try
和except
的计算要求非常高。所以我的问题是:
答案 0 :(得分:2)
我创造了解决问题的方法。它可能与少量的数据点相关,以适应两节之间,所以我做的是用以下代码替换我创建结数的行:
idx_knots = (np.arange(1,len(x)-1,(len(x)-2)/np.double(nknots))).astype('int')
knots = x[idx_knots]
通过这种方式,我确保结之间有足够的数据点,因为我使用x向量的索引。
答案 1 :(得分:1)
您可以使用t
参数,而不是直接指定结(通过s
参数)。
s
参数控制样条曲线的平滑度。它通过增加结的数量来实现它,直到条件
sum((w * (y - g))**2,axis=0) <= s
满足(g是平滑样条曲线表示,w是权重)。