使用Python适合分段函数

时间:2011-11-17 21:55:47

标签: python numpy

我正在尝试使用Numpy来使用绝对值来拟合分段函数。

数学函数是

x< p [1]:y = 1 + p [0] * abs((尺寸+ x - p [1])/尺寸 - 尺寸/ 2)

x> = p [1]:y = 1 + p [0] * abs((x - p [1])/ size - size / 2)

这是我的Python函数:

fitfunc = lambda p, x: \
    x < p[1] and\
    1 + p[0] * abs((data['n1'].size + x - p[1]) / data['n1'].size - data['n1'].size / 2) or\
    1 + p[0] * abs((x - p[1]) / data['n1'].size - data['n1'].size / 2)

虽然,我收到了错误:

The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

然而,any和all将整个列表评估为单个布尔值。

更多信息:

我使用lambdas通过使用以下内容将数据拟合到正弦波:

fitfunc = lambda p, x: 1 + p[0] * sin(pi * x / data['n1'].size + p[1])
errfunc = lambda p, x, y: fitfunc(p, x) - y # Distance to the target function

然后循环:

data = np.genfromtxt(dataFileName, names=('n1', 'n2'))
xAxisSeries = scipy.linspace(0., data['n1'].max(), data['n1'].size)

p0 = [489., 123.] # Initial guess for the parameters
p1, success = scipy.optimize.leastsq(errfunc, p0[:], args=(xAxisSeries, data['n2']))

#time says which points from the sine wave will be plotted
time = scipy.linspace(0., data['n1'].max(), 100)
pylab.plot(time, fitfunc(p1, time), 'r-')

我正在尝试使用lambda函数,因为optimize.leastsq需要一个。我正在使用完全相同的代码,但fitfunc被更改除外。

3 个答案:

答案 0 :(得分:2)

上面的代码看起来并不惯用,并且使生活变得更加艰难。 :)

如果您尝试定义一个函数并同时为其命名,则传统方法是使用 def ,而不是 lambda

fitfunc = lambda p, x: ...  ## you're making a named function, so just do...

def fitfunc(p, x): ...

一旦你拥有了它,你就不必用'和'和'或'来模拟短路分支:你可以使用 if 。您在尝试模拟 if 时遇到了麻烦。

答案 1 :(得分:0)

说实话,目前还不清楚你要用lambda函数做什么。 但也许这就是我在世界各地的时间......

在任何情况下,请注意,任何(somelist)和np.array()。any()都是相同的,但可以不同方式调用。

In [2]: a=np.ones(4)

In [3]: a
Out[3]: array([ 1.,  1.,  1.,  1.])
In [4]: a.any()
Out[4]: True

In [8]: a[1]=0

In [9]: a.all()
Out[9]: False

In [11]: somelist=["1","1","a","3"]

In [12]: any(somelist)
Out[12]: True

请注意评论,你怎么称呼这个功能?你能发布更多代码吗?

答案 2 :(得分:0)

使用def和scipy.optimize.curve_fit()。

import scipy.optimize as so

def fitfunc(p, x):
    '''Define fit function'''
    if x < p[1]:
        return 1 + p[0] * abs((data['n1'].size + x - p[1]) / data['n1'].size - data['n1'].size / 2)
    else:
        return 1 + p[0] * abs((x - p[1]) / data['n1'].size - data['n1'].size / 2)

popt, pcov = so.curve_fit(fitfunc, x, y)