这是我的代码:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from scipy.optimize import least_squares
##################################### Prepare Data #########################################
file = 'https://aegis4048.github.io/downloads/notebooks/sample_data/decline_curve.xlsx'
df = pd.read_excel(file, sheet_name='sheet_1')
df = df[df['Oil Prod. (bopd)'] > 200] # remove bad data points
t = df['Time'][1:].values[: -40]
y = df['Oil Prod. (bopd)'][1:].values[:-40]
x = np.array([i for i in range(len(t))])
############################################################################################
def hyperbolic(x, qi, b, Di):
return qi / (1 + b * Di * x) ** (1 / b)
res_robust = least_squares(hyperbolic, x0=[max(y), 0.1, 0.1], args=(x, y))
使用以下语法,我可以轻松地将其与curve_fit
配合使用:
popt, pcov = curve_fit(hyperbolic, x, y, maxfev=100000, p0=[max(y), 0.1, 0.1])
但是当我尝试使用least_squares
来拟合数据时,出现了以下错误消息:
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-1-5ee2dcc8876d> in <module>()
20 return qi / (1 + b * Di * x) ** (1 / b)
21
---> 22 res_robust = least_squares(hyperbolic, x0=[max(y), 0.1, 0.1], args=(x, y,))
C:\ProgramData\Anaconda3\lib\site-packages\scipy\optimize\_lsq\least_squares.py in least_squares(fun, x0, jac, bounds, method, ftol, xtol, gtol, x_scale, loss, f_scale, diff_step, tr_solver, tr_options, jac_sparsity, max_nfev, verbose, args, kwargs)
797 x0 = make_strictly_feasible(x0, lb, ub)
798
--> 799 f0 = fun_wrapped(x0)
800
801 if f0.ndim != 1:
C:\ProgramData\Anaconda3\lib\site-packages\scipy\optimize\_lsq\least_squares.py in fun_wrapped(x)
792
793 def fun_wrapped(x):
--> 794 return np.atleast_1d(fun(x, *args, **kwargs))
795
796 if method == 'trf':
TypeError: hyperbolic() missing 1 required positional argument: 'Di'
我不了解curve_fit
和least_squares
之间的操作区别。有人可以给我一个适用于least_squares
的有效代码吗?
答案 0 :(得分:1)
根据least_squares
文档,您的fun
应具有签名:
fun(x, *args, **kwargs)
换句话说,它正在尝试:
hyperbolic(x0, x, y) # 3 arguments
x
的形状与您的x0
初始值匹配; (x,y)
来自args
参数。
对于curve_fit
的期望是
ydata = f(xdata, *params)
所以打电话吧
hyperbolic(x, p0[0], p0[1], p0[2]) # line up with
#hyperbolic(x, qi, b, Di)
您的hyperbolic
签名与curve_fit
调用匹配,但与least_squares
调用不匹配。