Python 将对数曲线拟合到数据点,并以numpy进行外推

Python 将对数曲线拟合到数据点,并以numpy进行外推,python,numpy,matplotlib,curve-fitting,Python,Numpy,Matplotlib,Curve Fitting,我有一组数据点(代码中的x和y)。我想画出这些点,并拟合一条曲线,显示使y=100.0所需的x值(y值是百分比)。这是我尝试过的,但我的曲线是3次多项式(我知道这是错误的)。对我来说,数据看起来是对数的,但我现在知道如何将对数曲线拟合到我的数据 import numpy as np import matplotlib.pyplot as plt x = np.array([4,8,15,29,58,116,231,462,924,1848]) y = np.array([1.05,2.11,3

我有一组数据点(代码中的x和y)。我想画出这些点,并拟合一条曲线,显示使y=100.0所需的x值(y值是百分比)。这是我尝试过的,但我的曲线是3次多项式(我知道这是错误的)。对我来说,数据看起来是对数的,但我现在知道如何将对数曲线拟合到我的数据

import numpy as np
import matplotlib.pyplot as plt

x = np.array([4,8,15,29,58,116,231,462,924,1848])
y = np.array([1.05,2.11,3.95,7.37,13.88,25.46,43.03,64.28,81.97,87.43])

for x1, y1 in zip(x,y):
    plt.plot(x1, y1, 'ro')

z = np.polyfit(x, y, 3)
f = np.poly1d(z)

for x1 in np.linspace(0, 1848, 110):
    plt.plot(x1, f(x1), 'b+')

plt.show()

我解决这类问题的方法是使用
scipy.optimize.curve\u fit
。当然,这是一个必须从导入的函数,
scipy.optimize

该函数将使用定义f(x,a,b)定义的一个函数作为第一个参数。函数必须将自变量作为第一个参数,所有其他参数都应该是函数的参数。
然后,
.curve_fit()
获取x数据,然后获取y数据(1-D数组很好)。它返回一个具有最佳拟合参数的数组。最后你应该有这样的东西

import numpy as np
from scipy.optimize import curve_fit

def l( x, a, b, c, d ):
    return a*np.log( b*x + c ) + d

param = curve_fit( l, x, y )

我解决这类问题的方法是使用
scipy.optimize.curve\u fit
。当然,这是一个必须从导入的函数,
scipy.optimize

该函数将使用定义f(x,a,b)定义的一个函数作为第一个参数。函数必须将自变量作为第一个参数,所有其他参数都应该是函数的参数。
然后,
.curve_fit()
获取x数据,然后获取y数据(1-D数组很好)。它返回一个具有最佳拟合参数的数组。最后你应该有这样的东西

import numpy as np
from scipy.optimize import curve_fit

def l( x, a, b, c, d ):
    return a*np.log( b*x + c ) + d

param = curve_fit( l, x, y )
它看起来像一个绑定:

在这种情况下,严格地说,y=100%只会发生在x=inf时,它看起来像一个绑定:


在这种情况下,严格地说,y=100%只发生在x=inf时,实际上不需要使用Numpy或Scipy的任何拟合函数,因为有一个“简单”的函数。下面是Python的一个实现:

def logFit(x,y):
    # cache some frequently reused terms
    sumy = np.sum(y)
    sumlogx = np.sum(np.log(x))

    b = (x.size*np.sum(y*np.log(x)) - sumy*sumlogx)/(x.size*np.sum(np.log(x)**2) - sumlogx**2)
    a = (sumy - b*sumlogx)/x.size

    return a,b
然后,您可以将其应用于您的问题,如下所示:

x = np.array([4,8,15,29,58,116,231,462,924,1848])
y = np.array([1.05,2.11,3.95,7.37,13.88,25.46,43.03,64.28,81.97,87.43])

def logFunc(x, a, b):
    return a + b*np.log(x)

plt.plot(x, y, ls="none", marker='.')

xfit = np.linspace(0,2000,num=200)
plt.plot(xfit, logFunc(xfit, *logFit(x,y)))
不过,我不认为你的数据是对数的:


实际上,您不需要使用Numpy或Scipy的任何拟合函数,因为有一个“简单”的函数。下面是Python的一个实现:

def logFit(x,y):
    # cache some frequently reused terms
    sumy = np.sum(y)
    sumlogx = np.sum(np.log(x))

    b = (x.size*np.sum(y*np.log(x)) - sumy*sumlogx)/(x.size*np.sum(np.log(x)**2) - sumlogx**2)
    a = (sumy - b*sumlogx)/x.size

    return a,b
然后,您可以将其应用于您的问题,如下所示:

x = np.array([4,8,15,29,58,116,231,462,924,1848])
y = np.array([1.05,2.11,3.95,7.37,13.88,25.46,43.03,64.28,81.97,87.43])

def logFunc(x, a, b):
    return a + b*np.log(x)

plt.plot(x, y, ls="none", marker='.')

xfit = np.linspace(0,2000,num=200)
plt.plot(xfit, logFunc(xfit, *logFit(x,y)))
不过,我不认为你的数据是对数的:

“…但我不知道如何将对数曲线多边形拟合到我的数据”您不会使用
polyfit
将对数函数拟合到数据。看看“…但我不知道如何将对数曲线拟合到我的数据”您不会使用
polyfit
将对数函数拟合到数据。看一看。