python - 减少样条插值中的振荡
问题描述
我正在尝试使用该UnivariateSpline
函数对一组点进行插值,但是我在该组的限制中得到了通常的大振荡,你知道有什么方法可以解决这个问题吗?
我的代码如下所示:
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
x=pd.read_csv('thrustlaw.txt')
x1=x['Time(sec)']
y1=x['Thrust(N)']
def splines(x1,y1):
from scipy.interpolate import UnivariateSpline
si = UnivariateSpline(x1,y1,s=0, k=3)
xs = np.linspace(0, x1[len(x1)-1], 10000)
ys = si(xs)
plt.plot(x1,y1,'go')
plt.plot(xs, ys)
plt.ylabel("Thrust[N]")
plt.xlabel("Time[sec]")
plt.title("Thrust curve (splines)")
plt.grid()
plt.show()
splines(x1,y1)
结果:
解决方案
将高次多项式拟合到噪声数据往往会做到这一点。没有这个问题的插值方法是(唯一的)分段三次多项式,对于每对连续点i, i+1
:
- 穿过去
x_i, y_i
- 穿过去
x_{i+1}, y_{i+1}
- 在
x_i
, 有斜率(y_{i+1} - y_{i-1}) / (x_{i+1} - x_{i-1})
- 在
x_{i+1}
, 有斜率(y_{i+2} - y_i) / (x_{i+2} - x_i)
所以每一点的切线都平行于从上一点到下一点的直线段。这迫使导数与原始数据“有些相似”,因此它不会剧烈振荡。
如果我没记错的话,这是一个 Catmull-Rom spline,一个三次 Hermite spline的特例。也许这个问题会帮助你在 scipy 中实现它,或者找到另一种你喜欢的插值方法。
推荐阅读
- c# - 添加迁移期间的“无主键”消息
- selenium-webdriver - 如何使用 Selenium Web Driver 一一点击所有链接?
- python-3.x - 如何从 Python 中的 3D 点的 Delaunay 三角剖分生成四面体?
- laravel - Laravel Horizon 不读取会话
- javascript - 使用 Viewerjs 显示 CORS 问题
- javascript - 如何返回具有最小值键的对象数组?
- sql - Ssms 服务器不读取阿拉伯字母
- html - 如何删除路由器链接添加到VueJS中的按钮的边距
- swift - NSCollectionViewItem 和对可访问性的支持
- javascript - v-on 处理程序中的错误:“TypeError:无法将未定义或 null 转换为对象”