曲线拟合分段函数?

时间:2016-07-08 17:14:46

标签: python numpy scipy ipython

正如标题所示,我试图用分段函数进行曲线拟合。这是一个例子:

import numpy as np
import scipy.optimize as sio

x = np.array([0, 1, 2, 3, 4, 5])
y = np.array([2, 3, 4, 11, 18, 27])

def f(x, a):
    if x <= 2:
        return x + a
    elif x >= 3:
        return x**2 + a

sio.curve_fit(f, x, y)

现在,这会返回以下错误:

ValueError: The truth value of an array with more than one element is ambiguous

通过添加打印功能,我发现这是因为&#39; x&#39;价值传递给函数&#39; f&#39;是numpy数组[0, 1, 2, 3, 4, 5]

我想知道这个问题是否有解决办法。

谢谢!

2 个答案:

答案 0 :(得分:1)

总体问题是您为标量编写了f,但xa是numpy数组。您的if行以及return语句中的if都属于这种情况。

与您的代码最相似的解决方案是:

import numpy as np
import scipy.optimize as sio

x = np.array([0, 1, 2, 3, 4, 5])
y = np.array([2, 3, 4, 11, 18, 27])

def f(x, a):
    y = np.zeros(len(x))
    for i, xi in enumerate(x): 
        if xi <= 2:
            y[i] =  xi + a
        elif xi >= 3:
            y[i] =  xi**2 + a
    return y

sio.curve_fit(f, x, y)

f的更多矢量化定义是:

def f(x, a):
    y = np.zeros(len(x))
    y[:3] += a
    y[3:] = x[3:]**2 + a
    return y

答案 1 :(得分:1)

这是一种可以使用np.boolean数组的问题。如果你有大量的数据,它比循环数组更有效,并允许你使用任意表达式作为你的if / else条件。

import numpy as np
import scipy.optimize as sio

x = np.array([0, 1, 2, 3, 4, 5])
y = np.array([2, 3, 4, 11, 18, 27])

def f(x, a):
    y = np.zeros(len(x))
    y += (x + a) * (x <= 2)
    y += (x ** 2 + a) * (x >= 3)
    return y

sio.curve_fit(f, x, y)

其中x <= 2 =

[True, True, True, False, False, False]

可以在numpy表达式中使用:

[1, 1, 1, 0, 0, 0]