使用python通过点拟合曲线

Posted

技术标签:

【中文标题】使用python通过点拟合曲线【英文标题】:Fit a curve through points using python 【发布时间】:2019-10-10 08:47:23 【问题描述】:

大家好,我正在尝试使用 python 通过点拟合曲线,但是我没有成功,我是使用 python 的初学者,我发现它对我没有帮助。

我有一组数据,我想分析哪一行最能描述它(不同阶的多项式)。

numpy 中,对于多项式拟合,有polyfit()polyval()。但是我收到了这个错误,我不知道这是什么意思:

File "plantilla.py", line 28, in <module>
polinomio=np.polyfit(x,y,5)
File "/usr/lib/python2.7/dist-packages/numpy/lib/polynomial.py", line 581,   in polyfit
c, resids, rank, s = lstsq(lhs, rhs, rcond)
File "/usr/lib/python2.7/dist-packages/numpy/linalg/linalg.py", line 1867,  in lstsq
0, work, lwork, iwork, 0)
ValueError: On entry to DLASCL parameter number 4 had an illegal value

import pandas as pd 
from matplotlib import pyplot as plt  
from scipy.optimize import curve_fit
import numpy as np
import sympy as sym

#----------------------------------------------------
data=pd.read_csv('radiacion.dat',header=None,delim_whitespace=True) 
x=data.ix[:,0] 
y=data.ix[:,1]
"""
x=np.array(x,dtype=float)
y=np.array(y,dtype=float)
"""
#----------------------------------------------------
plt.plot(x,y,'r',label="Original Data")
plt.title('Radiacion')
plt.xlabel('t(s)'  ,fontsize=14,fontweight='bold')
plt.ylabel('G(w/m)',fontsize=14,fontweight='bold')
plt.xticks(fontsize=10,fontweight='bold')
plt.yticks(fontsize=10,fontweight='bold')
plt.show ()
#plt.hold (True) 
#----------------------------------------------------
polinomio=np.polyfit(x,y,5)
print (polinomio)
yP=np.polyval(poli,x)
plt.plot(x,yp,'b+',label="fitted cuerve")

我期待这样的事情,以特定的x 值评估多项式。

p[0]*x**(N-1) + p[1]*x**(N-2) + ... + p[N-2]*x + p[N-1]

我的输入数据:

25200   17
25800   38
26400   58
27000   93
27600   129
28200   163
28800   192
29400   234
30000   329
30600   387
31200   411
31800   460
32400   513
33000   569
33600   576
34200   635
34800   645
35400   683
36000   715
36600   747
37200   780
37800   810
38400   833
39000   862
39600   885
40200   910
40800   929
41400   945
42000   955
42600   974
43200   986
43800   985
44400   999
45000   1001
45600   993
46200   993
46800   999
47400   992
48000   985
48600   980
49200   978
49800   963
50400   959
51000   939
51600   917
52200   884
52800   881
53400   860
54000   845
54600   820
55200   812
55800   767
56400   720
57000   650
57600   619
58200   595
58800   541
59400   533
60000   504
60600   456
61200   389
61800   320
62400   285
63000   243
63600   279
64200   231
64800   192
65400   137
66000   91
66600   58
67200   38
67800   22
68400   9

【问题讨论】:

您的 x 或 y 值中是否有 NaNinf 没有权限读取文件,不知能否确保数据本身不包含infnan?参考:github.com/statsmodels/statsmodels/issues/3596 @G.Anderson 和 Yi Bao,你们两个好,我的数据文件中没有任何“NaN”或“inf”,我已经发布了我的数据。提前谢谢你。 在问题行polinomio=np.polyfit(x,y,5)之前打印我们的xy参数是什么,你提到的错误可能来自于传递一个对于x或@来说太短的列表987654337@。你得到你所期望的了吗? 我使用了您的数据,就像您在保存在 txt 文件中的问题上粘贴的一样。我没有收到任何错误!我认为您的原始文件有问题。 【参考方案1】:

我使用的数据与您粘贴在 txt 文件中的问题完全一样。我没有收到任何错误!我认为您的原始文件有问题。

这是输出。

【讨论】:

【参考方案2】:

使用三阶多项式特征曲线拟合 X 数据列,然后使用线性回归创建表示曲线拟合的线段

data = np.array([[25200, 17],
             [25800, 38],
             [26400, 58],
             [27000, 93],
             [27600, 129],
             [28200, 163],
             [28800, 192],
             [29400, 234],
             [30000, 329],
             [30600, 387],
             [31200, 411],
             [31800, 460],
             [32400, 513],
             [33000, 569],
             [33600, 576],
             [34200, 635],
             [34800, 645],
             [35400, 683],
             [36000, 715],
             [36600, 747],
             [37200, 780],
             [37800, 810],
             [38400, 833],
             [39000, 862],
             [39600, 885],
             [40200, 910],
             [40800, 929],
             [41400, 945],
             [42000, 955],
             [42600, 974],
             [43200, 986],
             [43800, 985],
             [44400, 999],
             [45000, 1001],
             [45600, 993],
             [46200, 993],
             [46800, 999],
             [47400, 992],
             [48000, 985],
             [48600, 980],
             [49200, 978],
             [49800, 963],
             [50400, 959],
             [51000, 939],
             [51600, 917],
             [52200, 884],
             [52800, 881],
             [53400, 860],
             [54000, 845],
             [54600, 820],
             [55200, 812],
             [55800, 767],
             [56400, 720],
             [57000, 650],
             [57600, 619],
             [58200, 595],
             [58800, 541],
             [59400, 533],
             [60000, 504],
             [60600, 456],
             [61200, 389],
             [61800, 320],
             [62400, 285],
             [63000, 243],
             [63600, 279],
             [64200, 231],
             [64800, 192],
             [65400, 137],
             [66000, 91],
             [66600, 58],
             [67200, 38],
             [67800, 22],
             [68400, 9]])

print(data.shape)

X=data[:, 0].reshape(-1,1)
y=data[:, 1]

min_X=min(X)
max_X=max(X)
poly = PolynomialFeatures(degree=3)
X_poly = poly.fit_transform(X)

X_new = np.linspace(min_X,max_X).reshape(-1, 1)
X_new_poly = poly.transform(X_new)

linreg = LinearRegression().fit(X_poly, y)
y_new = linreg.predict(X_new_poly)

plt.plot(X,y,'r')
plt.plot(X_new, y_new)
plt.xlabel('t(s)',fontsize=14,fontweight='bold')
plt.title('Radiacion')
plt.show()

【讨论】:

以上是关于使用python通过点拟合曲线的主要内容,如果未能解决你的问题,请参考以下文章

python numpy/scipy曲线拟合

通过更改python中的模型函数进行通用曲线拟合

通过特定多项式拟合 Python 曲线

如何使用 C++ 将点拟合到曲线?

已知所有点,怎么用OpenCV写正弦的拟合曲线?

离散点怎么拟合成曲线啊