簡體   English   中英

如何在Python中應用2D曲線擬合?

[英]How to apply a 2D curve fit in Python?

我正在嘗試應用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

最終目的是開發Z = f(X,T)形式的相關性

首先,使用二次表達式Z = a * x ^ 2 + b * x + c沿T的恆定值(即沿每行)進行曲線擬合,如下所示作為每個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中完成?

我只是玩了一下,我想你的問題是台詞

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,)只是一維數組的處理方式不同。 嘗試一下,看看是否可行。

也就是說,我不確定擬合參數是否是解決此問題的正確方法,至少就我所知...

我可以借此機會無恥地插入自己的配件包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)

有關更多信息,請檢查docs :)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM