【问题标题】:Pass Pandas DataFrame to Scipy.optimize.curve_fit将 Pandas DataFrame 传递给 Scipy.optimize.curve_fit
【发布时间】:2016-05-15 23:48:14
【问题描述】:

我想知道使用 Scipy 拟合 Pandas DataFrame 列的最佳方法。如果我有一个包含列(ABCDZ_real)的数据表(Pandas DataFrame),其中 Z 取决于 A、B、C 和 D,我想拟合每个 DataFrame 行(系列)的函数,它对 Z 进行预测(Z_pred)。

要拟合的每个函数的签名是

func(series, param_1, param_2...)

其中 series 是对应 DataFrame 每一行的 Pandas Series。我使用 Pandas 系列,以便不同的功能可以使用不同的列组合。

我已经尝试将 DataFrame 传递给 scipy.optimize.curve_fit 使用

curve_fit(func, table, table.loc[:, 'Z_real'])

但由于某种原因,每个 func 实例都将整个数据表作为其第一个参数而不是每一行的 Series 传递。我也尝试将 DataFrame 转换为 Series 对象列表,但这会导致我的函数被传递一个 Numpy 数组(我认为是因为 Scipy 执行从 Series 列表到不保留 Pandas 的 Numpy 数组的转换系列对象)。

【问题讨论】:

    标签: python pandas scipy mathematical-optimization model-fitting


    【解决方案1】:

    您对curve_fit 的呼叫不正确。来自the documentation

    xdata一个长度为 M 的序列或一个 (k,M) 形的数组,用于具有 k 个预测变量的函数。

    测量数据的自变量。

    ydata : M-length 序列

    依赖数据——名义上是 f(xdata, ...)

    在这种情况下,您的自变量xdata 是A 到D 列,即table[['A', 'B', 'C', 'D']],而您的因变量ydatatable['Z_real']

    还要注意xdata应该是一个(k, M)数组,其中k是预测变量(即列)的数量,M 是观察数(即行)。因此,您应该转置输入数据帧,使其为 (4, M) 而不是 (M, 4),即 table[['A', 'B', 'C', 'D']].T

    curve_fit 的整个调用可能如下所示:

    curve_fit(func, table[['A', 'B', 'C', 'D']].T, table['Z_real'])
    

    这是一个显示多元线性回归的完整示例:

    import numpy as np
    import pandas as pd
    from scipy.optimize import curve_fit
    
    X = np.random.randn(100, 4)     # independent variables
    m = np.random.randn(4)          # known coefficients
    y = X.dot(m)                    # dependent variable
    
    df = pd.DataFrame(np.hstack((X, y[:, None])),
                      columns=['A', 'B', 'C', 'D', 'Z_real'])
    
    def func(X, *params):
        return np.hstack(params).dot(X)
    
    popt, pcov = curve_fit(func, df[['A', 'B', 'C', 'D']].T, df['Z_real'],
                           p0=np.random.randn(4))
    
    print(np.allclose(popt, m))
    # True
    

    【讨论】:

    • 感谢您的回复。我已经尝试过了,但是发送给 func 的第一个参数仍然是整个(现在转置和裁剪)DataFrame,而不是对应于它应该是的每一行的系列。我之前没有裁剪表格的原因是func 本身隔离了它需要使用的每个系列中的值(因为不同的拟合函数使用不同的自变量组合),所以如果它 Z_real 包含在系列中它通过了就没有区别了。
    • 如果您显示您的 func 定义会很有帮助 - 听起来它的签名与 curve_fit 期望的不兼容
    • 我已经更改了代码以尽可能地适应文档(包括使用 Numpy 而不是 Pandas),但我遇到了同样的问题。 func(X, p1, p2) 现在是return p1*X[0] + p2*X[1] 的形式,我将拟合函数称为curve_fit(func, xdata, ydata),其中xdata 是一个2x111 数组,ydata 是一个长度为111 的数组。问题是在func 中放置一个打印函数仍然显示 X 等于 xdata(一个 2x111 数组),而不是 xdata 的特定列(一个 2x1 数组)。
    • 我不明白你为什么期望Xxdata 的单列。在我的示例中,传递给 funcX 参数是 df[['A', 'B', 'C', 'D']].T,即 (4, 100) 数据帧,而不是单个列。对于多元线性回归,您需要所有这些列,因为您通过对由参数向量加权的自变量值求和来预测y
    • 那么也许我只是使用了错误的 Scipy 函数来完成这项工作。在我的问题中,func 预测 Z 的单个值,给定 A、B、C 和 D 中的每一个的单个值以及一些常量参数(即z_i = func(a_i, b_i, c_i|params) = p_1*a_i + p_2*b_i + p_3*c_i),尽管func 应该能够是任意的-适合该签名的订单函数。我想使用我的实验数据表找到最佳参数,以在给定这些输入的情况下对 Z 进行最佳整体预测。
    猜你喜欢
    • 2012-11-19
    • 2021-12-27
    • 2020-03-07
    • 2021-05-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多