使用 scipy.optimize.curve_fit() 将表面拟合到 3D 散点数据时出现类型错误
TypeError when fitting surface to 3D scatter data using scipy.optimize.curve_fit()
我有一个 Pandas DataFrame,其列包含 x、y 和 z 值。
import pandas as pd
df = pd.DataFrame({'Age': x,
'Mileage': y,
'Price': z})
使用 scipy.optimize.curvefit()
我能够拟合单变量指数函数 y = exp(-bx)
:
import numpy as np
from scipy.optimize import curve_fit
# fit y to x
def exp_function(x, a, b):
return a * np.exp(-b * x)
popt, pcov = curve_fit(exp_function, df['Age'], # x-values
df['Price'], # y-values
absolute_sigma=False, maxfev=1000)
# popt
# array([2.81641498e+04, 1.29183078e-01]) # a, b-values
但是当我尝试将相同的分析扩展到 3D 时,我遇到了 TypeError
:
# fit z to (x, y)
def exp_function_2(x, y, a, b, c):
return (a/2) * (np.exp(-b * x) + np.exp(-c * y))
popt, pcov = curve_fit(exp_function_2,
df['Age'], # x-values
df['Mileage'], # y-values
df['Price'], # z-values
absolute_sigma=False, maxfev=1000)
# TypeError: exp_function_2() takes 5 positional arguments but 1518 were given
它似乎认为我正在将 1518 个参数(我的 Pandas 数据帧的长度)传递给 exp_function_2()
。
为什么我的代码适用于 2D (x, y)
适配,但在 3D (x, y, z)
适配上却卡住了?
您正在使用不正确的参数调用该方法。
原型为curve_fit(f, xdata, ydata, p0=None, ...)
的docs indicate,其中p0
是您函数参数的起始猜测。所以在你有一个 TypeError
的情况下,你将框架的所有 1518 个元素作为默认参数传递给你的函数,当然它只接受 5 个参数。事实上,您的代码在 2D 情况下工作是一个快乐的巧合,根本没有使用 p0
关键字参数。
您需要在 xdata
中将两个预测变量作为单个参数传递,然后将它们解包到指数函数中。像这样的东西(虽然我不确定我的数据帧索引是否正确,但我很少使用 pandas):
def exp_function_2(x, a, b, c):
return (a/2) * (np.exp(-b * x['Age']) + np.exp(-c * x['Mileage']))
我有一个 Pandas DataFrame,其列包含 x、y 和 z 值。
import pandas as pd
df = pd.DataFrame({'Age': x,
'Mileage': y,
'Price': z})
使用 scipy.optimize.curvefit()
我能够拟合单变量指数函数 y = exp(-bx)
:
import numpy as np
from scipy.optimize import curve_fit
# fit y to x
def exp_function(x, a, b):
return a * np.exp(-b * x)
popt, pcov = curve_fit(exp_function, df['Age'], # x-values
df['Price'], # y-values
absolute_sigma=False, maxfev=1000)
# popt
# array([2.81641498e+04, 1.29183078e-01]) # a, b-values
但是当我尝试将相同的分析扩展到 3D 时,我遇到了 TypeError
:
# fit z to (x, y)
def exp_function_2(x, y, a, b, c):
return (a/2) * (np.exp(-b * x) + np.exp(-c * y))
popt, pcov = curve_fit(exp_function_2,
df['Age'], # x-values
df['Mileage'], # y-values
df['Price'], # z-values
absolute_sigma=False, maxfev=1000)
# TypeError: exp_function_2() takes 5 positional arguments but 1518 were given
它似乎认为我正在将 1518 个参数(我的 Pandas 数据帧的长度)传递给 exp_function_2()
。
为什么我的代码适用于 2D (x, y)
适配,但在 3D (x, y, z)
适配上却卡住了?
您正在使用不正确的参数调用该方法。
原型为curve_fit(f, xdata, ydata, p0=None, ...)
的docs indicate,其中p0
是您函数参数的起始猜测。所以在你有一个 TypeError
的情况下,你将框架的所有 1518 个元素作为默认参数传递给你的函数,当然它只接受 5 个参数。事实上,您的代码在 2D 情况下工作是一个快乐的巧合,根本没有使用 p0
关键字参数。
您需要在 xdata
中将两个预测变量作为单个参数传递,然后将它们解包到指数函数中。像这样的东西(虽然我不确定我的数据帧索引是否正确,但我很少使用 pandas):
def exp_function_2(x, a, b, c):
return (a/2) * (np.exp(-b * x['Age']) + np.exp(-c * x['Mileage']))