gpt4 book ai didi

python - 如何在 pyomo 模型中提取索引变量信息并构建 Pandas Dataframe

转载 作者:行者123 更新时间:2023-12-05 03:41:56 26 4
gpt4 key购买 nike

我正在尝试使用具有多个不同大小的索引变量的 Pyomo 来解决 MIP。我想做的是将变量的结果导出到数据框,以便我可以进一步分析这些结果。我的问题是我无法找到一种很好地自动化该过程的方法,因为索引变量的大小在每个模型模拟中都会发生变化。

这是我要创建的一些变量的示例:

import pyomo.environ as pyo

model = pyo.ConcreteModel()

model.T = pyo.RangeSet(0, 10)
model.Generators = pyo.Set(initialize=(['equip_1', 'equip_2']))
model.Storages = pyo.Set(initialize=(['storage_1', 'storage_2']))

model.var_1 = pyo.Var(model.T, model.Generators, domain=pyo.NonNegativeReals)
model.var_2 = pyo.Var(model.T, domain=pyo.NonNegativeReals)
model.var_3 = pyo.Var(model.T, model.Storages, domain=pyo.NonNegativeReals)
model.var_4 = pyo.Var(model.T, model.Generators, domain=pyo.Binary, initialize=0)

# constraints and objective function here, which I don't think are relevant for the question
.
.
.
SolverFactory('cbc').solve(model).write()

现在,我想创建数据框,其中 model.T 作为索引,变量名加上 model.Generator 或 model.Storages 作为 multiIndex 列(我假设它必须是 multiIndex,但也许不是).下面显示了我希望它看起来如何的粗略示例:

  |      Var_1      | Var_2 |        Var_3        |      Var_4
| equip_1 equip_2 | None | storage_1 storage_2 | equip_1 equip_2
m | 0 | 0 | 0 | 0 | 0 | 0 | 1
o | 1 | 1 | 1 | 1 | 1 | 1 | 0
d | 2 | 2 | 2 | 2 | 2 | 0 | 1
e | 3 | 3 | 3 | 3 | 3 | 1 | 0
l | 4 | 4 | 4 | 4 | 4 | 0 | 1
. | 5 | 5 | 5 | 5 | 5 | 1 | 0
T | 6 | 6 | 6 | 6 | 6 | 0 | 1

显示的值只是示例。此外,model.T 不必是索引,因为它与使用数据框创建的标准索引相关联。

我一直在竭尽全力试图让它发挥作用,但我正在努力在 pyomo 中找到正确的语法。我觉得必须有一种简单的方法来提取这些数据,因为我不是第一个尝试这样做的人,但我已经在互联网上搜索了这个特定问题但无济于事。我遇到的问题是尝试以简单的循环或矢量化方式从变量结果中提取变量索引(model.T 和 model.Generators/Storages)。

拜托!任何建议将不胜感激。如果我还不够清楚,请告诉我。

最佳答案

完全可行...

首先,让我们介绍一个基本示例,说明如何(在一般意义上)在求解后从 pyomo 中获取结果。回想一下,求解器完成后,变量的最优值将加载到模型变量中。这是一个简单的示例,显示了从变量中提取数据的 3 种方法。还有很多其他的,这取决于需要做什么。值得注意的是,这里的最后一个方法,转换为字典,是转换到 pandas 的关键,因为我们都知道 pandas 喜欢字典。

# extracting values 1
import pyomo.environ as pyo
import pandas as pd

m = pyo.ConcreteModel('value extraction')

m.S = pyo.Set(initialize=range(3))
m.X = pyo.Var(m.S, initialize={0:-1, 1:2.5, 2:12}) # just initializing to simulate solving

# show all of X
m.X.display()

# iterate through and show values
print()
for s in m.S:
print(f'for index {s} X[{s}] is: {m.X[s].value}')

# dump into a dictionary.... an entry point for pandas!
print()
print(m.X.extract_values())

# make a pd.Series indexed by the index set(s)
print()
x_vals = pd.Series(m.X.extract_values(), name=m.X.name)
print(x_vals)

yield :

X : Size=3, Index=S
Key : Lower : Value : Upper : Fixed : Stale : Domain
0 : None : -1 : None : False : False : Reals
1 : None : 2.5 : None : False : False : Reals
2 : None : 12 : None : False : False : Reals

for index 0 X[0] is: -1
for index 1 X[1] is: 2.5
for index 2 X[2] is: 12

{0: -1, 1: 2.5, 2: 12}

0 -1.0
1 2.5
2 12.0
Name: X, dtype: float64

第二部分:

好的,接下来构建一个更全面的解决方案来应对将整个结果混合到多索引数据帧中的挑战。值得注意的是,我初始化了其中的变量值来模拟求解。通常,变量不需要。

所以这建立在之前的概念之上,即 pd.Series 只是一个由索引数组索引的数组,可以从字典构造。我不是最聪明的 pandas 运算符(operator),所以可能有一些方法可以组合一些 pd 命令,但谁在乎呢?这是循序渐进的,如果您正在处理来自优化的变量,它不会太大,因此不需要调整。

# extracting values 2
import pyomo.environ as pyo
import pandas as pd

model = pyo.ConcreteModel()

model.T = pyo.RangeSet(0, 10)
model.Generators = pyo.Set(initialize=(['equip_1', 'equip_2']))
model.Storages = pyo.Set(initialize=(['storage_1', 'storage_2']))

model.var_1 = pyo.Var(model.T, model.Generators, initialize=1.5, domain=pyo.NonNegativeReals)
model.var_2 = pyo.Var(model.T, initialize=2.5, domain=pyo.NonNegativeReals)
model.var_3 = pyo.Var(model.T, model.Storages, initialize=3.5, domain=pyo.NonNegativeReals)
model.var_4 = pyo.Var(model.T, model.Generators, domain=pyo.Binary, initialize=0)

#model.display()

# let's convert each var to a pandas series, indexed by model.T...

# get all the variables (assuming the fuller model will have constraints, params, etc.)
model_vars = model.component_map(ctype=pyo.Var)


serieses = [] # collection to hold the converted "serieses"
for k in model_vars.keys(): # this is a map of {name:pyo.Var}
v = model_vars[k]

# make a pd.Series from each
s = pd.Series(v.extract_values(), index=v.extract_values().keys())

# if the series is multi-indexed we need to unstack it...
if type(s.index[0]) == tuple: # it is multi-indexed
s = s.unstack(level=1)
else:
s = pd.DataFrame(s) # force transition from Series -> df
#print(s)

# multi-index the columns
s.columns = pd.MultiIndex.from_tuples([(k, t) for t in s.columns])

serieses.append(s)

df = pd.concat(serieses, axis=1)
print(df)

产量

     var_1         var_2     var_3             var_4        
equip_1 equip_2 0 storage_1 storage_2 equip_1 equip_2
0 1.5 1.5 2.5 3.5 3.5 0 0
1 1.5 1.5 2.5 3.5 3.5 0 0
2 1.5 1.5 2.5 3.5 3.5 0 0
3 1.5 1.5 2.5 3.5 3.5 0 0
4 1.5 1.5 2.5 3.5 3.5 0 0
5 1.5 1.5 2.5 3.5 3.5 0 0
6 1.5 1.5 2.5 3.5 3.5 0 0
7 1.5 1.5 2.5 3.5 3.5 0 0
8 1.5 1.5 2.5 3.5 3.5 0 0
9 1.5 1.5 2.5 3.5 3.5 0 0
10 1.5 1.5 2.5 3.5 3.5 0 0

关于python - 如何在 pyomo 模型中提取索引变量信息并构建 Pandas Dataframe,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67491499/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com