我有一些数据,y
与x
,我想用三次样条插值到更精细的分辨率xx
。
以下是我的数据集:
import numpy as np
print np.version.version
import scipy
print scipy.version.version
字符串
1.9.2
0.15.1
x = np.array([0.5372973, 0.5382103, 0.5392305, 0.5402197, 0.5412042, 0.54221, 0.543209,
0.5442277, 0.5442277, 0.5452125, 0.546217, 0.5472153, 0.5482086,
0.5492241, 0.5502117, 0.5512249, 0.5522136, 0.5532056, 0.5532056,
0.5542281, 0.5552039, 0.5562125, 0.5567836])
y = np.array([0.01, 0.03108, 0.08981, 0.18362, 0.32167, 0.50941, 0.72415, 0.90698,
0.9071, 0.97955, 0.99802, 1., 0.97863, 0.9323, 0.85344, 0.72936,
0.56413, 0.36997, 0.36957, 0.17623, 0.05922, 0.0163, 0.01, ])
xx = np.array([0.5372981, 0.5374106, 0.5375231, 0.5376356, 0.5377481, 0.5378606,
0.5379731, 0.5380856, 0.5381981, 0.5383106, 0.5384231, 0.5385356,
0.5386481, 0.5387606, 0.5388731, 0.5389856, 0.5390981, 0.5392106,
0.5393231, 0.5394356, 0.5395481, 0.5396606, 0.5397731, 0.5398856,
0.5399981, 0.5401106, 0.5402231, 0.5403356, 0.5404481, 0.5405606,
0.5406731, 0.5407856, 0.5408981, 0.5410106, 0.5411231, 0.5412356,
0.5413481, 0.5414606, 0.5415731, 0.5416856, 0.5417981, 0.5419106,
0.5420231, 0.5421356, 0.5422481, 0.5423606, 0.5424731, 0.5425856,
0.5426981, 0.5428106, 0.5429231, 0.5430356, 0.5431481, 0.5432606,
0.5433731, 0.5434856, 0.5435981, 0.5437106, 0.5438231, 0.5439356,
0.5440481, 0.5441606, 0.5442731, 0.5443856, 0.5444981, 0.5446106,
0.5447231, 0.5448356, 0.5449481, 0.5450606, 0.5451731, 0.5452856,
0.5453981, 0.5455106, 0.5456231, 0.5457356, 0.5458481, 0.5459606,
0.5460731, 0.5461856, 0.5462981, 0.5464106, 0.5465231, 0.5466356,
0.5467481, 0.5468606, 0.5469731, 0.5470856, 0.5471981, 0.5473106,
0.5474231, 0.5475356, 0.5476481, 0.5477606, 0.5478731, 0.5479856,
0.5480981, 0.5482106, 0.5483231, 0.5484356, 0.5485481, 0.5486606,
0.5487731, 0.5488856, 0.5489981, 0.5491106, 0.5492231, 0.5493356,
0.5494481, 0.5495606, 0.5496731, 0.5497856, 0.5498981, 0.5500106,
0.5501231, 0.5502356, 0.5503481, 0.5504606, 0.5505731, 0.5506856,
0.5507981, 0.5509106, 0.5510231, 0.5511356, 0.5512481, 0.5513606,
0.5514731, 0.5515856, 0.5516981, 0.5518106, 0.5519231, 0.5520356,
0.5521481, 0.5522606, 0.5523731, 0.5524856, 0.5525981, 0.5527106,
0.5528231, 0.5529356, 0.5530481, 0.5531606, 0.5532731, 0.5533856,
0.5534981, 0.5536106, 0.5537231, 0.5538356, 0.5539481, 0.5540606,
0.5541731, 0.5542856, 0.5543981, 0.5545106, 0.5546231, 0.5547356,
0.5548481, 0.5549606, 0.5550731, 0.5551856, 0.5552981, 0.5554106,
0.5555231, 0.5556356, 0.5557481, 0.5558606, 0.5559731, 0.5560856,
0.5561981, 0.5563106, 0.5564231, 0.5565356, 0.5566481, 0.5567606])
型
我尝试使用scipy InterpolatedUnivariateSpline
方法拟合,用三阶样条k=3
插值,并外推为零ext='zeros'
:
import scipy.interpolate as interp
yspline = interp.InterpolatedUnivariateSpline(x,y, k=3, ext='zeros')
yvals = yspline(xx)
import matplotlib.pyplot as plt
fig = plt.figure()
ax = fig.add_subplot(111)
ax.plot(x, y, 'ko', label='Values')
ax.plot(xx, yvals, 'b-.', lw=2, label='Spline')
plt.xlim([min(x), max(x)])
型
x1c 0d1x的数据
然而,正如你在这张图中看到的,我的样条函数返回NaN
值:(有原因吗?我很确定我的x值都在增加,所以我很难理解为什么会发生这种情况。我有很多其他的数据集,我用这个方法拟合,它只在这个特定的数据集上失败。
任何帮助都非常感谢。谢谢你的阅读。
编辑!
解决方案是,我有重复的x
值,不同的y
值!
3条答案
按热度按时间11dmarpk1#
对于这种插值,您应该使用带有参数
kind='cubic'
的scipy.interpolate.interp1d
(参见related SO question)我还没有找到一个可以在实践中使用
InterpolatedUnivariateSpline
的用例(或者我只是不理解它的用途)。所以插值工作,但显示出非常强烈的振荡,使它无法使用,这是典型的结果,我得到了这种插值方法在过去。与较低的阶样条(例如
k=1
),工作得更好,但然后你失去了三次插值的优势。rnmwe5a22#
在x()数组中,有两个相邻的值,它们分别等于0.5442277和0.5442277,这是由@rth观察到的。(但更糟糕的是,如果你仔细看,它们是两对重复的:0.5442277、0.5442277和0.5532056、0.5532056)。样条函数通常假设输入x()和y()向量中的值是唯一的。在初步计算期间使用秩通常会导致结-这不是唯一的。
在样条函数中,相邻函数之间存在大量的差分,其中许多增量被用作插值函数。如果两个相邻函数,即x(i)和x(i+1)或y(i)和y(i+1)相同,则增量为零。分母为零的结果为无穷大;然而,结果通常最终为NaN --因为您在计算过程中没有足够早地捕捉到它。
我经常使用的一种解决方法是向x()和y()的每个值添加一点噪声,以随机均匀变量的形式缩小到机器精度U(0,1)* 1 e-12。
我也不调用(使用)不是我从头开始开发的函数或子程序,所以我通常不必研究第三方库中发生了什么。
k7fdbhmy3#
我也遇到过
InterpolatedUnivariateSpline
返回NaN值的问题。但在我的情况下,原因不是在x
数组中有重复,而是因为当docs声明值“必须 * 增加 *"时,x
中的值 * 减少 *。因此,在这种情况下,代替原始的
x
和y
,必须提供相反的x[::-1]
和y[::-1]
。