当前位置:   article > 正文

插值与拟合_python插值拟合

python插值拟合

1.插值与拟合 

        在Python中,插值(interpolation)和拟合(fitting)是两种常用的数据处理技术,用于对数据进行平滑、补全或者拟合模型,以便更好地进行数据分析和预测。

  1. 插值(Interpolation): 插值是一种用于填补数据中缺失值或者对数据进行平滑处理的技术。当我们在一组已知数据点之间寻找未知数据点时,可以使用插值方法来估计这些未知点的数值。在Python中,常用的插值方法包括线性插值、多项式插值、样条插值等。

    使用Scipy库中的interp1d函数可以进行线性插值和样条插值,其中interp1d函数通过指定插值的数据点和插值方法来生成插值函数。另外,Numpy库中的polyfit函数可以用于多项式拟合,其中polyfit函数通过指定多项式的阶数来生成拟合函数。

  2. 拟合(Fitting): 拟合是一种用于找到最优模型来逼近已知数据的技术。当我们有一组离散的数据点,并希望找到一个函数或者模型,使其能够较好地拟合这些数据点时,可以使用拟合方法来找到最佳拟合参数。在Python中,拟合通常使用Scipy库或者Numpy库中的函数来实现。

    使用Scipy库中的curve_fit函数可以进行非线性拟合,其中curve_fit函数通过指定拟合函数和初始参数值来找到最优拟合参数。对于线性拟合,可以使用Numpy库中的polyfit函数,其也可用于多项式拟合,通过指定多项式的阶数来找到最佳拟合参数。

2.示例

2.1

使用线性插值和样条插值得到插值曲线,使用多项式拟合得到拟合曲线

  1. import numpy as np
  2. import matplotlib.pyplot as plt
  3. from scipy.interpolate import interp1d
  4. from scipy.optimize import curve_fit
  5. # 原始数据
  6. x = np.array([0, 1, 2, 3, 4, 5])
  7. y = np.array([0, 2, 3, 4, 2, 1])
  8. # 插值
  9. # 使用线性插值生成插值函数f_linear
  10. f_linear = interp1d(x, y, kind='linear')
  11. # 使用样条插值生成插值函数f_spline
  12. f_spline = interp1d(x, y, kind='cubic')
  13. # 生成新的x值,用于插值和拟合结果的展示
  14. x_new = np.linspace(0, 5, 100)
  15. # 使用线性插值函数f_linear对x_new进行插值,得到y_linear
  16. y_linear = f_linear(x_new)
  17. # 使用样条插值函数f_spline对x_new进行插值,得到y_spline
  18. y_spline = f_spline(x_new)
  19. # 多项式拟合
  20. # 定义多项式拟合函数,参数x为自变量,a、b、c为待拟合的参数
  21. def polynomial_func(x, a, b, c):
  22. return a * x**2 + b * x + c
  23. # 使用curve_fit函数拟合多项式函数,得到最优参数popt
  24. popt, _ = curve_fit(polynomial_func, x, y)
  25. # 使用拟合得到的最优参数popt,对x_new进行拟合,得到y_polyfit
  26. y_polyfit = polynomial_func(x_new, *popt)
  27. # 绘图
  28. plt.scatter(x, y, label='Data') # 绘制原始数据散点图
  29. plt.plot(x_new, y_linear, label='Linear Interpolation') # 绘制线性插值曲线
  30. plt.plot(x_new, y_spline, label='Cubic Spline Interpolation') # 绘制样条插值曲线
  31. plt.plot(x_new, y_polyfit, label='Polynomial Fitting') # 绘制多项式拟合曲线
  32. plt.legend() # 添加图例
  33. plt.xlabel('x') # x轴标签
  34. plt.ylabel('y') # y轴标签
  35. plt.show() # 显示图形

 2.2

线性插值与样条插值

        已知温度为T=[700,720,740,760,780]时,过热蒸汽体积的变化为V=[0.0977,0.1218,

0.1406,0.1551,0.1664],分别采用线性插值和三次样条插值求解T=750,770时的体积变化,并在一个图形界面中画出线性插值和三次插值函数。

        线性插值(Linear Interpolation)和三次样条插值(Cubic Spline Interpolation)都是常用的插值方法,用于在给定的一组数据点之间插值得到未知数据点的数值。它们都可以用于平滑数据、补全数据或者预测中间值。

  1. 线性插值(Linear Interpolation): 线性插值是最简单的插值方法之一。在线性插值中,我们假设两个已知数据点之间的数值变化是线性的。给定两个已知数据点 (x0, y0)(x1, y1),线性插值可以通过以下公式来计算在两个点之间任意 x 处的插值 y

    y = y0 + (x - x0) * (y1 - y0) / (x1 - x0)

    线性插值的优点是简单且快速,但可能不适用于高度非线性的数据。

  2. 三次样条插值(Cubic Spline Interpolation): 三次样条插值是一种更复杂的插值方法,它在给定的数据点之间使用一组三次多项式来插值。三次样条插值保证在每个数据段上都有二阶连续导数,因此能够更好地逼近复杂曲线。

    三次样条插值通过以下步骤实现:

    • 首先,在每个相邻数据点之间拟合一个三次多项式,这些多项式称为“分段三次多项式”。
    • 然后,通过要求插值函数在每个数据点处满足一阶导数连续性和二阶导数连续性,确定插值函数的系数。

    三次样条插值的优点是能够很好地逼近数据的曲线特性,通常比线性插值更精确。

  1. import numpy as np
  2. import pylab as plt
  3. from scipy.interpolate import interp1d
  4. # 原始数据
  5. T0 = np.linspace(700, 780, 5)
  6. V0 = np.array([0.0977, 0.1218, 0.1406, 0.1551, 0.1664])
  7. # 要插值的目标温度
  8. T = [750, 770]
  9. # 线性插值
  10. fv1 = interp1d(T0, V0)
  11. # 三次样条插值
  12. fv2 = interp1d(T0, V0, 'cubic')
  13. # 对目标温度进行插值
  14. V1 = fv1(T)
  15. V2 = fv2(T)
  16. # 生成更密集的温度数据,用于插值结果的展示
  17. xn = np.linspace(700, 780, 81)
  18. vn1 = fv1(xn)
  19. vn2 = fv2(xn)
  20. # 绘图展示结果
  21. plt.rc('font', family="SimHei") # 设置字体为中文
  22. plt.plot(xn, vn1, '-*', label="线性插值") # 绘制线性插值曲线
  23. plt.plot(xn, vn2, '.-', label="三次样条插值") # 绘制三次样条插值曲线
  24. plt.scatter(T, V1, c='r', marker='o', label="线性插值目标点") # 标记线性插值目标点
  25. plt.scatter(T, V2, c='b', marker='s', label="三次样条插值目标点") # 标记三次样条插值目标点
  26. plt.legend() # 添加图例
  27. plt.xlabel('温度 (T)') # x轴标签
  28. plt.ylabel('体积 (V)') # y轴标签
  29. plt.title('线性插值与三次样条插值') # 图标题
  30. plt.show() # 显示图形

2.3

考虑矩形区域 x∈ [-3,3] ,y∈[-4,4]上的函数

 利用随机数生成函数uniform随机生成改矩形内的散乱点,用griddata函数进行插值处理,并做出插值结果图形。

  1. import numpy as np
  2. import matplotlib.pyplot as plt
  3. import numpy.random as nr
  4. from scipy.interpolate import griddata
  5. # 定义函数z
  6. z = lambda x, y: (x**2 - 2*x) * np.exp(-x**2 - y**2 - x*y)
  7. # 在[-3, 3]和[-4, 4]的范围内随机生成60个样本点
  8. x0 = nr.uniform(-3, 3, 60)
  9. y0 = nr.uniform(-4, 4, 60)
  10. # 计算样本点的函数值
  11. z0 = z(x0, y0)
  12. # 在[-3, 3]和[-4, 4]范围内生成61个均匀间隔的点作为插值的目标网格
  13. xn = np.linspace(-3, 3, 61)
  14. yn = np.linspace(-4, 4, 81)
  15. xn, yn = np.meshgrid(xn, yn)
  16. # 将样本点和函数值组合成一个二维数组
  17. xy0 = np.vstack([x0, y0]).T
  18. # 使用三次样条插值计算目标网格上的插值结果
  19. zn1 = griddata(xy0, z0, (xn, yn), method='cubic')
  20. # 使用最近邻插值计算目标网格上的插值结果
  21. zn2 = griddata(xy0, z0, (xn, yn), method='nearest')
  22. # 绘制图形
  23. fig = plt.figure(figsize=(12, 5))
  24. # 绘制原函数的图形
  25. ax1 = plt.subplot(121, projection='3d')
  26. ax1.plot_surface(xn, yn, z(xn, yn), cmap='summer')
  27. ax1.set_title('原函数图像')
  28. # 绘制三次样条插值的图形
  29. ax2 = plt.subplot(122, projection='3d')
  30. ax2.plot_surface(xn, yn, zn1, cmap='winter')
  31. ax2.set_title('三次样条插值图像')
  32. plt.show()

 

 

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/一键难忘520/article/detail/803805
推荐阅读
相关标签
  

闽ICP备14008679号