首页 文章

如何在Python中应用2D曲线拟合?

提问于
浏览
0

我正在尝试应用2D曲线拟合数据(任意)集合,如下所示:

# Data
T   Z   X 1 X 2 X 3 X 4 X 5
100.000 1.000   1.000   1.478   1.304   1.162   0.805
200.000 1.500   2.000   2.314   2.168   2.086   1.801
300.000 2.250   3.000   3.246   3.114   3.058   2.798
400.000 3.375   4.000   4.211   4.087   4.044   3.780
500.000 5.063   5.000   5.189   5.070   5.035   4.780

The ultimate aim is to develop a correlation of the form Z = f(X, T) .

首先,使用沿着T的常数值的二次表达式Z = a * x ^ 2 b * x c进行曲线拟合,即沿着每行,这给出了如下给出的每个T的拟合参数(作为示例):

T   a   b   c
100.00  1.00    2.10    10.02
200.00  4.00    6.20    10.06
300.00  9.00    12.30   10.12
400.00  16.00   20.40   10.20
500.00  25.00   30.50   10.31

现在我想在T中拟合每个拟合参数,以便得到形式a = p * T ^ 2 q * T r,b = s * T ^ 2 t * T u等的方程式 . 我尝试应用这个使用代码:

from __future__ import division
from scipy import optimize
import matplotlib.pyplot as plt
import numpy as np

data = open('data.dat', "r")
line = data.readline()
while line.startswith('#'):
    line = data.readline()
data_header = line.split("\t")
data_header[-1] = data_header[-1].strip()


_data_ = np.genfromtxt('data.dat', skiprows=2, delimiter='\t', names = data_header, dtype = None, unpack = True).transpose()
data = np.array(_data_.tolist())
m = data.shape[0]
n = data.shape[1] - 2
print m, n
y_data = np.empty(shape=(m, n))
for i in range(0, m):
    for j in range(0, n):
        y_data[i, j] = (data[i, j+2])
x = _data_['X']
z = _data_['Z']

def quadratic_fit(x, a, b, c):
    return a * x ** 2 + b * x + c

fit_a = np.empty(shape = (m, 1))
fit_b = np.empty(shape = (m, 1))
fit_c = np.empty(shape = (m, 1))
z_fit = np.empty(shape=(m, len(z)))
for j in range(m):
    x_fit = y_data[j, :]
    y_fit = z
    fit_a[j], fit_b[j], fit_c[j] = optimize.curve_fit(quadratic_fit, x_fit, y_fit)[0]
fit_a_fit_a, fit_a_fit_b, fit_a_fit_c, = optimize.curve_fit(quadratic_fit, x, fit_a)[0]
fit_b_fit_a, fit_b_fit_b, fit_b_fit_c, = optimize.curve_fit(quadratic_fit, x, fit_b)[0]
fit_c_fit_a, fit_c_fit_b, fit_c_fit_c, = optimize.curve_fit(quadratic_fit, x, fit_c)[0]
fit_a = fit_a_fit_a * x ** 2 + fit_a_fit_b * x + fit_a_fit_c
fit_b = fit_b_fit_a * x ** 2 + fit_b_fit_b * x + fit_b_fit_c
fit_c = fit_c_fit_a * x ** 2 + fit_c_fit_b * x + fit_c_fit_c
for j in range(m):              
    z_fit[j, :] = (fit_a[j] * x_fit ** 2) + (fit_b[j] * x_fit) + fit_c[j]

但它给了我以下错误:

ValueError: object too deep for desired array
Traceback (most recent call last):
    fit_a_fit_a, fit_a_fit_b, fit_a_fit_c, = optimize.curve_fit(quadratic_fit, x, fit_a)[0]
  File "scipy/optimize/minpack.py", line 533, in curve_fit
    res = leastsq(func, p0, args=args, full_output=1, **kw)
  File "scipy/optimize/minpack.py", line 378, in leastsq
    gtol, maxfev, epsfcn, factor, diag)
minpack.error: Result from function call is not a proper array of floats.

如何在Python中完成?

2 回答

  • 0

    我只是玩了一下,我认为你的问题就是线条

    fit_a = np.empty(shape = (m, 1))
    fit_b = np.empty(shape = (m, 1))
    fit_c = np.empty(shape = (m, 1))
    

    应该

    fit_a = np.empty(shape = (m, ))
    fit_b = np.empty(shape = (m, ))
    fit_c = np.empty(shape = (m, ))
    

    当然看起来形状(m,1)应该是正确的,但它不像形状(m,)那样仅仅是一维数组 . 试试看,看看它是否有效 .

    也就是说,我不确定拟合度参数是解决这个问题的正确方法,至少据我所知...

  • 0

    我可以借此机会无耻地插上我自己的试衣包symfit吗?

    我精心开发它可以使您的装配问题更容易 . 没有为你的问题运行它,这就是我用 symfit 解决它的方法:

    from symfit import parameters, variables, Fit
    
    Z, X, T = variables('Z, X, T')
    p, q, r, s, t, u  = parameters('p, q, r, s, t, u')
    
    a = p * T**2 + q * T + r
    b = s * T**2 + t * T + u
    c = ...
    model = {Z: a * X ** 2 + b * X + c}
    
    fit = Fit(model, X=_data_['X'], T=_data_['T'], Z=_data_['Z'])
    fit_result = fit.execute()
    
    print(fit_result)
    

    有关详细信息,请查看文档:) .

相关问题