Python已知坐标点数值拟合出n次多项式

问题描述

已知坐标点的数值,如(x_1,y_1), (x_2,y_2)...,通过程序拟合出他们之间的函数曲线。

(这里我的需求是拟合出n次多项式,以后还可以扩展到指数函数、对数函数...)


1.引入库

代码如下:

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sympy import *


2.读入数据

代码如下:

#数据表格
df = pd.read_csv(r'C:/Users/hanhan/PycharmProjects/pythonProject/data1.csv',encoding = 'gbk')
df1 = pd.read_csv(r'C:/Users/hanhan/PycharmProjects/pythonProject/data2.csv',encoding = 'gbk')

3.求解步骤

完整版代码如下:

①首先定义两个空列表,一个用来存x的值,一个用来存y的值。

②通过for循环计算得出x和y的值,如果是已知明确的数值,不需要计算的,可以直接调到for循环的下面代码部分。

③将x和y的值输入到np.polyfit(x,y,3)函数中,3的意思是指3次多项式,根据实际情况设定。

④因为是3次多项式,所以得到的结果有四个数,分别是三个多项式系数及一个常数项。按照对应系数画出拟合出来的函数线条(也可以加上坐标的散点图)

plt.plot(x,y,'bo',ms = 5)
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sympy import *

#数据表格
df = pd.read_csv(r'C:/Users/hanhan/PycharmProjects/pythonProject/data1.csv',encoding = 'gbk')
df1 = pd.read_csv(r'C:/Users/hanhan/PycharmProjects/pythonProject/data2.csv',encoding = 'gbk')

#参数定义

a0 = []
a1 = []
q = 1

for i in range(len(df)):
    M_sj = np.array(df['shijian1'].iloc[i:i + q])
    N_sj = np.array(df['shijian2'].iloc[i:i + q])
    L_sj = np.array(df1['shijian3'].iloc[i:i + q])

    constant1 = 2 * (L_sj) / (M_sj + N_sj)
    constant2 = -2 * (M_sj) / (N_sj + L_sj)

    a0.append(constant1[0])
    a1.append(constant2[0])

x = a0
x = np.array(x)
print('x is :\n',x)
print('x is :\n',x.shape)

y = a1
y = np.array(y)
print('y is :\n',y)
#用3次多项式拟合
f = np.polyfit(x, y, 3)
print('f is :\n',f)

df1.to_csv(r'C:\\Users\\hanhan\\PycharmProjects\\pythonProject\\alldata.csv', encoding='gbk')

# 设置x的坐标范围
x=np.arange(0,100,0.01)
# 转化为网格
# x,y=np.meshgrid(x,y)
y = f[0] * np.power(x,3) + f[1] * np.power(x,2) + f[2] * np.power(x,1) + f[3]
plt.scatter(x, y, c='r')
plt.show()

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我会尽力回答你的问题。首先,最小二乘法是一种常见的数据方法,可以用来求一个函数的参数,使得该函数与一组给定的数据点最为接近。在多项式中,我们可以用一个多项式函数来给定的数据点,使得该函数能够经过这些点。假设我们要用一个n次多项式函数来给定的m个数据点,那么我们可以列如下的方程组: ![image.png](attachment:image.png) 其中,x_i 和 y_i 分别表示第i个数据点的横坐标和纵坐标,a_0, a_1, ..., a_n 分别表示多项式的系数。该方程组可以用矩阵表示为: ![image-2.png](attachment:image-2.png) 其中,X是一个m×(n+1)的矩阵,其中每一行都表示一个数据点,每一列都表示多项式的一个系数;y是一个m×1的向量,其中每个元素都表示对应数据点的纵坐标;a是一个(n+1)×1的向量,其中每个元素都表示多项式的一个系数。 我们可以用列主元素消去法来求解该方程组,具体步骤如下: 1.将增广矩阵[A|b]化为上三角矩阵[U|c],其中U是一个n×(n+1)的矩阵,c是一个n×1的向量。 2.从最后一行开始,依次解每个未数的值。 3.将求得的未数代入原方程中,得到曲线的经验公式。 4.根据经验公式,求新的点,并与原来的数据点进行对比。 下面是用C++编写的最小二乘法多项式的程序: ```c++ #include <iostream> #include <iomanip> #include <cmath> using namespace std; const int MAXN = 10; const double eps = 1e-10; int n; // 多项式的次数 double a[MAXN][MAXN], b[MAXN], x[MAXN]; // 系数矩阵、常数向量、解向量 // 列主元素消去法解线性方程组 bool gauss() { int i, j, k, p; double maxa, t; for (k = 0; k < n; ++k) { maxa = 0.0; for (i = k; i < n; ++i) { if (fabs(a[i][k]) > maxa) { maxa = fabs(a[i][k]); p = i; } } if (maxa < eps) return false; // 奇异矩阵 if (p != k) { for (j = k; j <= n; ++j) { swap(a[k][j], a[p][j]); } swap(b[k], b[p]); } for (i = k + 1; i < n; ++i) { t = a[i][k] / a[k][k]; for (j = k + 1; j <= n; ++j) { a[i][j] -= t * a[k][j]; } b[i] -= t * b[k]; } } for (i = n - 1; i >= 0; --i) { for (j = i + 1; j < n; ++j) { b[i] -= a[i][j] * x[j]; } x[i] = b[i] / a[i][i]; } return true; } // 函数 double f(double x) { double res = 0.0; for (int i = 0; i <= n; ++i) { res += x * pow(x, i); } return res; } int main() { double data[MAXN][2] = {{0.4, 1.075}, {0.6, 1.115}, {0.8, 1.16}, {1.0, 1.225}}; n = 2; // 2次多项式 for (int i = 0; i <= n; ++i) { for (int j = 0; j <= n; ++j) { a[i][j] = 0.0; for (int k = 0; k < 4; ++k) { a[i][j] += pow(data[k][0], i + j); } } b[i] = 0.0; for (int k = 0; k < 4; ++k) { b[i] += pow(data[k][0], i) * data[k][1]; } } if (gauss()) { cout << "经验公式为:y = "; for (int i = n; i >= 0; --i) { if (i == n) { cout << x[i] << "x^" << i << " + "; } else if (i == 0) { cout << x[i] << endl; } else { cout << x[i] << "x^" << i << " + "; } } cout << "结果如下:" << endl; cout << setw(10) << "x" << setw(10) << "y1" << setw(10) << "y2" << endl; double x0 = 0.4, xn = 1.0, dx = 0.01; for (double xi = x0; xi <= xn; xi += dx) { double yi1 = f(xi); double yi2 = 0.0; for (int i = 0; i <= n; ++i) { yi2 += x[i] * pow(xi, i); } cout << setw(10) << xi << setw(10) << yi1 << setw(10) << yi2 << endl; } } else { cout << "无解" << endl; } return 0; } ``` 该程序中,我们首先定义了一个n×(n+1)的系数矩阵a和一个n×1的常数向量b,然后根据给定的数据点,计算这些系数和常数,构建一个线性方程组。接着,我们调用列主元素消去法求解该方程组,得到多项式的系数。最后,我们根据这些系数,求曲线的经验公式,并计算一组新的点,与原来的数据点进行对比。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值