Python 使用带有timeseries数据的熊猫数据帧作为SciPy优化的基础
我有一个数据帧(dfA)。数据帧dfB、dfP和dfR应通过优化计算。使用ScipPy minimize,我试图找到dfB和dfP的值,其中dfR中的残差之和最小。(dfR=dfA-(dfB+dfP)) 我设置了以下约束条件:Python 使用带有timeseries数据的熊猫数据帧作为SciPy优化的基础,python,pandas,optimization,dataframe,time-series,Python,Pandas,Optimization,Dataframe,Time Series,我有一个数据帧(dfA)。数据帧dfB、dfP和dfR应通过优化计算。使用ScipPy minimize,我试图找到dfB和dfP的值,其中dfR中的残差之和最小。(dfR=dfA-(dfB+dfP)) 我设置了以下约束条件: #defining constraints cons = ( {'type': 'ineq', 'fun': lambda x: x[0] + x[1] - int(dfA.max())}, # sum of b and p not grea
#defining constraints
cons = (
{'type': 'ineq', 'fun': lambda x: x[0] + x[1] - int(dfA.max())}, # sum of b and p not greater than max amount of dfA
{'type': 'ineq', 'fun': lambda x: x[0]}, # x[0] 0 or higher
{'type': 'ineq', 'fun': lambda x: x[1]}, # x[1] 0 or higher
{'type': 'ineq', 'fun': lambda x: x[0]-100}, # x[0] < 100
{'type': 'ineq', 'fun': lambda x: x[1]-100}, # x[1] <100
)
我称之为最小化,如下所示:
def optGoal(b, p, dfA, dfB, dfP):
dfB['b'] = b # set df Values to b, constant value for all existing indices
dfP['p'] = p # set df Values to p, constant value for all existing indices
dfR = dfA['LP1'] - (dfB['b'].add(dfP['p'], fill_value=0)) # df Residual = df Profile - (dfB + dfP) but fill the NAN values --- dfB['b'].add(dfP['p'], fill_value=0)
return dfR.sum()
print spo.minimize(lambda x: optGoal(x[0], x[1], dfA, dfB, dfP), [0,0], method='COBYLA', constraints = cons, options={'maxiter':50000}) # optimization and printing result
但优化没有成功:
status: 2
nfev: 50000
maxcv: 0.0
success: False
fun: -402779.92870763224
x: array([ 43388.11278667, 24835.78480024])
message: 'Maximum number of function evaluations has been exceeded.'
因此,我希望得到dfB(索引1到7)和dfP(索引3到6)的值,这将导致最小残差和(dfR)
与初始dfB和dfP创建一样,dfB中应该有一个值覆盖索引1到7,dfP中应该有一个值覆盖索引3到6
你能帮我解释一下我做错了什么吗?你的目标函数在两个变量上都是递减的,在b上有一个更陡的斜率,所以为了最小化它,你必须尽可能地增加b,如果你还有一些余量(你没有)。这将为您提供b=dfA.max(),p=0作为最小化函数的值。用计算机来做这件事就像用大锤敲开螺母一样。但我离题了 您的约束与您的意图不匹配(如注释中所述)。你想要这个:
cons = (
{'type': 'ineq', 'fun': lambda x: int(dfA.max()) - x[0] - x[1]}, # sum of b and p not greater than max amount of dfA
{'type': 'ineq', 'fun': lambda x: x[0]}, # x[0] 0 or higher
{'type': 'ineq', 'fun': lambda x: x[1]}, # x[1] 0 or higher
{'type': 'ineq', 'fun': lambda x: 100 - x[0]}, # x[0] < 100
{'type': 'ineq', 'fun': lambda x: 100 - x[1]}, # x[1] < 100
)
令我惊讶的是,计算出的解不在可行区域内。我不熟悉一般的scipy优化或数值优化,所以我不知道这是否符合预期。嗯,我想是的。很抱歉,我错把我的评论作为答案发布了。没问题。感谢您查看我的问题。如何将浮点值<0转换为int>=0?对于不在00:01和06:00之间的小时,dfR的值是什么?此外,“dfB和dfC中的值对于一年中的所有小时都应该相同(每个数据帧中的所有小时都保持不变)”我不清楚你的意思。我试着用一个更好的例子和代码来表达这个问题。@Markus查看我的编辑。我认为这些限制是错误的。这些注释是有意义的,但是函数与它们不匹配,并且实际上使您的问题在下面再次变得无界。非常感谢。我现在得到的结果与上面完全相同。我将目标函数更改为“return abs(dfR.sum()”,我得到的结果是:“x:array([29.7386825,17.95748859]),这对我来说有点奇怪,因为我使用Excel solver得到的结果是“x:array([40,0])。Excel解算器解决方案似乎更好,因为残差之和正好为0。
cons = (
{'type': 'ineq', 'fun': lambda x: int(dfA.max()) - x[0] - x[1]}, # sum of b and p not greater than max amount of dfA
{'type': 'ineq', 'fun': lambda x: x[0]}, # x[0] 0 or higher
{'type': 'ineq', 'fun': lambda x: x[1]}, # x[1] 0 or higher
{'type': 'ineq', 'fun': lambda x: 100 - x[0]}, # x[0] < 100
{'type': 'ineq', 'fun': lambda x: 100 - x[1]}, # x[1] < 100
)
status: 1
nfev: 99
fun: -210.0
message: 'Optimization terminated successfully.'
x: array([ 7.00000000e+01, -1.73472348e-18])
maxcv: 1.7347234759768071e-18
success: True