首页 > 解决方案 > 使用 scipy.optimize.curve_fit() 将曲面拟合到 3D 散射数据时出现 TypeError

问题描述

我有一个 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)拟合?

标签: pythonscipytypeerrorcurve-fittingscatter3d

解决方案


您正在使用不正确的参数调用该方法。

文档表明原型是curve_fit(f, xdata, ydata, p0=None, ...)p0函数参数的起始猜测在哪里。因此,如果您有 a TypeError,则将框架的所有 1518 个元素作为默认参数传递给您的函数,该函数当然只接受 5 个参数。p0您的代码在 2D 情况下工作的事实是完全不使用关键字参数的巧合。

您需要将两个预测变量作为单个参数传递给xdata,然后将它们解包到指数函数中。像这样的东西(虽然我不确定我的数据框索引是否正确,但我很少使用熊猫):

def exp_function_2(x, a, b, c):
    return (a/2) * (np.exp(-b * x['Age']) + np.exp(-c * x['Mileage']))

推荐阅读