scipy 使用1D数组进行曲线拟合时出现值错误

ny6fqffe  于 2022-11-10  发布在  其他
关注(0)|答案(2)|浏览(165)

我在使用Scipy曲线拟合获取拟合参数时遇到此错误(A,B,C,D)。定义的功能没有问题,工作正常,响应良好。当x(x11,x22)和y阵列(用于曲线拟合)只是一个元素数组,而不是具有一些元素的1D数组。我知道这个问题是因为在输入数组中有多个元素进行拟合(x11,x22,y).实际上,我认为这是因为代码不知道数组中的哪个元素应该应用函数中的条件.但是,我不知道如何解决它。任何帮助和建议将不胜感激!
下面是代码:

x11=fin[:,0]
x22=fin[:,1]
y=fin[:,2]

bin=[4,4.5,5,5.5]

def interpo(x,A,B, C, D):
    x1, x2=x
    if  bin[0] <= x1 <bin[1]:
        if np.logical_and(x2>= bin[0] , x2<bin[1]):
            f1=A + ((x1 -bin[0])/(bin[1]-bin[0]))*(B-A)
            f2=A + ((x2 -bin[0])/(bin[1]-bin[0]))*(B-A)
            kh=f2/f1
        if x2>= bin[1] and x2<bin[2]:
            f1=A + ((x1 -bin[0])/(bin[1]-bin[0]))*(B-A)
            f2=B + ((x2 -bin[1])/(bin[2]-bin[1]))*(C-B)
            kh=f2/f1

        if x2>= bin[2] and x2<bin[3]:
            f1=A + ((x1 -bin[0])/(bin[1]-bin[0]))*(B-A)
            f2=C + ((x2 -bin[2])/(bin[3]-bin[2]))*(D-C)
            kh=f2/f1
    if x1>= bin[1] and x1<bin[2]:
        if x2>= bin[1] and x2<bin[2]:
            f1=B + ((x1 -bin[1])/(bin[2]-bin[1]))*(C-B)
            f2=B + ((x2 -bin[1])/(bin[2]-bin[1]))*(C-B)
            kh=f2/f1
        if x2>= bin[2] and x2<bin[3]:
            f1=B + ((x1 -bin[1])/(bin[2]-bin[1]))*(C-B)
            f2=C + ((x2 -bin[2])/(bin[3]-bin[2]))*(D-C)
            kh=f2/f1
    if x1>= bin[2] and x1<bin[3]:
        if x2>= bin[2] and x2<bin[3]:
            f1=C + ((x1 -bin[2])/(bin[3]-bin[2]))*(D-C)
            f2=C + ((x2 -bin[2])/(bin[3]-bin[2]))*(D-C)
            kh=f2/f1

    return (kh)

popt, pcov = curve_fit(interpo, (x11,x22), y, method='lm')

下面是错误:

Input In [3] in interpo
    if  bin[0] <= x1 <bin[1]:

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

irlmq6kh1#

为了逐个计算x中的值,可以使用以下函数:

def interpo(x, A, B, C, D):
    result = []
    for x1, x2 in zip(x[0], x[1]):
        if  bin[0] <= x1 <bin[1]:
            if np.logical_and(x2>= bin[0] , x2<bin[1]):
                f1=A + ((x1 -bin[0])/(bin[1]-bin[0]))*(B-A)
                f2=A + ((x2 -bin[0])/(bin[1]-bin[0]))*(B-A)
                kh=f2/f1
            if x2>= bin[1] and x2<bin[2]:
                f1=A + ((x1 -bin[0])/(bin[1]-bin[0]))*(B-A)
                f2=B + ((x2 -bin[1])/(bin[2]-bin[1]))*(C-B)
                kh=f2/f1

            if x2>= bin[2] and x2<bin[3]:
                f1=A + ((x1 -bin[0])/(bin[1]-bin[0]))*(B-A)
                f2=C + ((x2 -bin[2])/(bin[3]-bin[2]))*(D-C)
                kh=f2/f1
        if x1>= bin[1] and x1<bin[2]:
            if x2>= bin[1] and x2<bin[2]:
                f1=B + ((x1 -bin[1])/(bin[2]-bin[1]))*(C-B)
                f2=B + ((x2 -bin[1])/(bin[2]-bin[1]))*(C-B)
                kh=f2/f1
            if x2>= bin[2] and x2<bin[3]:
                f1=B + ((x1 -bin[1])/(bin[2]-bin[1]))*(C-B)
                f2=C + ((x2 -bin[2])/(bin[3]-bin[2]))*(D-C)
                kh=f2/f1
        if x1>= bin[2] and x1<bin[3]:
            if x2>= bin[2] and x2<bin[3]:
                f1=C + ((x1 -bin[2])/(bin[3]-bin[2]))*(D-C)
                f2=C + ((x2 -bin[2])/(bin[3]-bin[2]))*(D-C)
                kh=f2/f1
        result.append(kh)        
    return result
yb3bgrhw

yb3bgrhw2#

我再次考虑到,为了适应这个函数,它似乎需要自由地处理numpy数组,所以我建议将它重写为这样一个替代方案:

def interpo(x, A, B, C, D):
    x1, x2 = x
    temp = np.zeros((x1.shape[0], 3))

    cond = np.logical_and(x1 >= bin[0], x1 < bin[1]) & np.logical_and(x2 >= bin[0], x2 < bin[1])
    temp[cond, 0] = A + ((x1[cond] -bin[0])/(bin[1]-bin[0]))*(B-A)
    temp[cond, 1] = A + ((x2[cond] -bin[0])/(bin[1]-bin[0]))*(B-A)

    cond = np.logical_and(x1 >= bin[0], x1 < bin[1]) & np.logical_and(x2 >= bin[1], x2 < bin[2])
    temp[cond, 0] = A + ((x1[cond] -bin[0])/(bin[1]-bin[0]))*(B-A)
    temp[cond, 1] = B + ((x2[cond] -bin[1])/(bin[2]-bin[1]))*(C-B)

    cond = np.logical_and(x1 >= bin[0], x1 < bin[1]) & np.logical_and(x2 >= bin[2], x2 < bin[3])
    temp[cond, 0] = A + ((x1[cond] -bin[0])/(bin[1]-bin[0]))*(B-A)
    temp[cond, 1] = C + ((x2[cond] -bin[2])/(bin[3]-bin[2]))*(D-C)

    cond = np.logical_and(x1 >= bin[1], x1 < bin[2]) & np.logical_and(x2 >= bin[1], x2 < bin[2])
    temp[cond, 0] = B + ((x1[cond] -bin[1])/(bin[2]-bin[1]))*(C-B)
    temp[cond, 1] = B + ((x2[cond] -bin[1])/(bin[2]-bin[1]))*(C-B)

    cond = np.logical_and(x1 >= bin[1], x1 < bin[2]) & np.logical_and(x2 >= bin[2], x2 < bin[3])
    temp[cond, 0] = B + ((x1[cond] -bin[1])/(bin[2]-bin[1]))*(C-B)
    temp[cond, 1] = C + ((x2[cond] -bin[2])/(bin[3]-bin[2]))*(D-C)

    cond = np.logical_and(x1 >= bin[2], x1 < bin[3]) & np.logical_and(x2 >= bin[2], x2 < bin[3])
    temp[cond, 0] = C + ((x1[cond] -bin[2])/(bin[3]-bin[2]))*(D-C)
    temp[cond, 1] = C + ((x2[cond] -bin[2])/(bin[3]-bin[2]))*(D-C)

    temp[:,2] = np.divide(temp[:,0], temp[:,1])

    return temp[:,2]

但是curve_fit()似乎无法适应这个函数的参数。请看下面的代码:

import numpy as np
from scipy.optimize import curve_fit

x11 = np.random.uniform(0.0, 3.0, 100)
x22 = np.random.beta(2.3, 4.8, 100) * 3.0

x11_int = x11.astype(np.int64)
x22_int = x22.astype(np.int64)

x22[x22_int < x11_int] = x22[x22_int < x11_int] + 1.0
x11_int = x11.astype(np.int64)
x22_int = x22.astype(np.int64)
x22[x22_int < x11_int] = x22[x22_int < x11_int] + 1.0
x11 = x11 / 2.0 + 4.0
x22 = x22 / 2.0 + 4.0

def interpo(x, A, B, C, D):
    x1, x2 = x
    temp = np.zeros((x1.shape[0], 3))

    cond = np.logical_and(x1 >= bin[0], x1 < bin[1]) & np.logical_and(x2 >= bin[0], x2 < bin[1])
    temp[cond, 0] = A + ((x1[cond] -bin[0])/(bin[1]-bin[0]))*(B-A)
    temp[cond, 1] = A + ((x2[cond] -bin[0])/(bin[1]-bin[0]))*(B-A)

    cond = np.logical_and(x1 >= bin[0], x1 < bin[1]) & np.logical_and(x2 >= bin[1], x2 < bin[2])
    temp[cond, 0] = A + ((x1[cond] -bin[0])/(bin[1]-bin[0]))*(B-A)
    temp[cond, 1] = B + ((x2[cond] -bin[1])/(bin[2]-bin[1]))*(C-B)

    cond = np.logical_and(x1 >= bin[0], x1 < bin[1]) & np.logical_and(x2 >= bin[2], x2 < bin[3])
    temp[cond, 0] = A + ((x1[cond] -bin[0])/(bin[1]-bin[0]))*(B-A)
    temp[cond, 1] = C + ((x2[cond] -bin[2])/(bin[3]-bin[2]))*(D-C)

    cond = np.logical_and(x1 >= bin[1], x1 < bin[2]) & np.logical_and(x2 >= bin[1], x2 < bin[2])
    temp[cond, 0] = B + ((x1[cond] -bin[1])/(bin[2]-bin[1]))*(C-B)
    temp[cond, 1] = B + ((x2[cond] -bin[1])/(bin[2]-bin[1]))*(C-B)

    cond = np.logical_and(x1 >= bin[1], x1 < bin[2]) & np.logical_and(x2 >= bin[2], x2 < bin[3])
    temp[cond, 0] = B + ((x1[cond] -bin[1])/(bin[2]-bin[1]))*(C-B)
    temp[cond, 1] = C + ((x2[cond] -bin[2])/(bin[3]-bin[2]))*(D-C)

    cond = np.logical_and(x1 >= bin[2], x1 < bin[3]) & np.logical_and(x2 >= bin[2], x2 < bin[3])
    temp[cond, 0] = C + ((x1[cond] -bin[2])/(bin[3]-bin[2]))*(D-C)
    temp[cond, 1] = C + ((x2[cond] -bin[2])/(bin[3]-bin[2]))*(D-C)

    temp[:,2] = np.divide(temp[:,0], temp[:,1])

    return (temp[:,2])

bin=[4,4.5,5,5.5]

y=interpo((x11, x22), 4.2, 0.9, 3.7, 11.0)

popt, pcov = curve_fit(interpo, (x11, x22), y, method='lm')

print(popt)

相关问题