繁体   English   中英

使用scipy_optimize进行优化

[英]Optimization using scipy_optimize

我正在尝试使用scipy.optimize的curve_fit优化函数。 这是我的代码。

import pandas as pd
import numpy as np
from scipy.optimize import curve_fit

xdata = [row[0] for row in pd.read_excel("C:\\Users\\310967\\Desktop\\Scholar\\Wound Chelation Draft\\ChelationFiles.xlsx", sheetname="Case2Data",skiprows=0).as_matrix()]
ydata = [row[1] for row in pd.read_excel("C:\\Users\\310967\\Desktop\\Scholar\\Wound Chelation Draft\\ChelationFiles.xlsx", sheetname="Case2Data",skiprows=0).as_matrix()]
SF = [row[4] for row in pd.read_excel("C:\\Users\\310967\\Desktop\\Scholar\\Wound Chelation Draft\\ChelationFiles.xlsx", sheetname="Case2Data",skiprows=0).as_matrix()]
uncertainty = [(np.sqrt(np.exp(np.log(a)**2)-1))*b for a,b in zip(SF, ydata)]

Tau = [0,1,5,7]



def func(x, I, E, ic1, ic2, ih1, ih2):

    def iu(t):
        return ((0.01295*np.exp(-0.645974*t))+(4.3688e-4*np.exp(-0.04251*t))+(5.642452e-5*np.exp(-0.00160863*t)))

    def ic(t,tj):
        if t > tj:
            return ic1*np.exp(-0.693/ih1*(t-tj))+ic1*np.exp(-0.693/ih1*(t-tj))
        else:
            return 0

    def listofic(t):
        list1 = []
        for tj in Tau:
            list1.append(ic(t,tj))
        return list1

    def Kj(tj):
        return iu(tj+1)*(E-1)/(ic(1,0)-iu(tj+1))

    def listofKj():
        list2 = []
        for tj in Tau:
            list2.append(Kj(tj))
        return list2

    Kjs = listofKj()

    def listofOneMinusKj(t):
        list3 = []
        for a in Tau:
            if t > a:
                value = 1-Kj(a)
            else:
                value = 1
            list3.append(value)
        return list3

    return (iu(x)*np.prod(listofOneMinusKj(x))+sum([a*b for a,b in zip(Kjs,listofic(x))]))*I


popt, pcov = curve_fit(func, xdata, ydata, sigma=uncertainty)
print(popt)

当我运行上面的代码时,出现错误,指出“具有多个元素的数组的真值不明确。请使用a.any()或a.all()”。 这是指函数OneMinusKj(t)中的“ if t> a”部分。

但是,如果我运行以下代码,尽管存在“ if t> a”,但代码仍会按预期运行。 我想知道上面的代码是什么问题。

import numpy as np
Tau = [0,1,5,7]

def func(x, I, E, ic1, ic2, ih1, ih2):

    def iu(t):
        return ((0.01295*np.exp(-0.645974*t))+(4.3688e-4*np.exp(-0.04251*t))+(5.642452e-5*np.exp(-0.00160863*t)))

    def ic(t,tj):
        if t > tj:
            return ic1*np.exp(-0.693/ih1*(t-tj))+ic1*np.exp(-0.693/ih1*(t-tj))
        else:
            return 0

    def listofic(t):
        list1 = []
        for tj in Tau:
            list1.append(ic(t,tj))
        return list1

    def Kj(tj):
        return iu(tj+1)*(E-1)/(ic(1,0)-iu(tj+1))

    def listofKj():
        list2 = []
        for tj in Tau:
            list2.append(Kj(tj))
        return list2

    Kjs = listofKj()

    def listofOneMinusKj(t):
        list3 = []
        for a in Tau:
            if t > a:
                value = 1-Kj(a)
            else:
                value = 1
            list3.append(value)
        return list3

    return (iu(x)*np.prod(listofOneMinusKj(x))+sum([a*b for a,b in zip(Kjs,listofic(x))]))*I

print(func(1,400,12.5,0.99,0.01,0.55,10))

Scipy优化曲线拟合过程会尝试将xdata的完整向量输入到函数func 您将其传递给listofOneMinusKj

因此, t > a (或作为x > a传递)产生布尔向量。 触发以下错误:

“具有多个元素的数组的真值不明确。请使用a.any()或a.all()”

发生此错误是因为您无法检查length > 1的向量是否为true。 如建议的那样,您可以使用(t > a).any()来检查t的任何值是否大于a或(t > a).all()来检查t所有值是否都更大。

调试此类问题的一种方法是引发import pdb; pdb.set_trace() import pdb; pdb.set_trace()位于回溯指向的行的上方。 然后运行您的代码,它会在断点处停下来---,您可以交互式地探索各种对象并逐步执行代码。 在这里,当您由curve_fit调用时,您可能会发现t或a是一个numpy数组,并且if array > another_array ,您将无法做到。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM