从 pandas DataFrame 在 pyomo 中定义参数
Define parameter in pyomo from pandas DataFrame
第一次使用 pyomo 用户。
我有一个定义模型的函数
def define_problem(SET_gen, SET_time, SET_buses, demand):
model = pyo.ConcreteModel()
#Define sets
model.SET_GEN = pyo.Set(initialize = SET_gen) #Set of generators
model.SET_TIME = pyo.Set(initialize = SET_time) #Set of hours
model.SET_BUSES = pyo.Set(initialize = SET_buses) #Set of buses
#Define parameters
model.DEMAND = pyo.Param(model.SET_BUSES, model.SET_TIME, initialize = demand_init)
...
函数中的参数'demand'是一个pandasDataFrame
函数demand_init定义如下
def demand_init(model, bus, t, data = demand):
if(bus in set(data.columns)):
return data.loc[t,bus]
return 0.0
需要为每个小时和每辆公交车定义参数model.DEMAND作为需求DataFrame中对应的'cell',如果公交车不在DataFrame中则为0。 编辑: 在 define_problem 函数外定义。
但是它不起作用。我如何从 pandas DataFrame 定义函数的参数?
EDIT: Thanks for the answers!
需求数据框如下所示:
Bus1 Bus10 Bus11 Bus12 ... Bus6 Bus7 Bus8 Bus9
Hour ...
1 0.0 9.00 3.50 6.10 ... 11.20 0.0 0.0 29.50
2 0.0 7.34 2.85 4.97 ... 9.13 0.0 0.0 24.06
3 0.0 6.45 2.51 4.37 ... 8.03 0.0 0.0 21.14
4 0.0 5.78 2.25 3.92 ... 7.20 0.0 0.0 18.95
5 0.0 5.56 2.16 3.77 ... 6.92 0.0 0.0 18.22
[5 rows x 14 columns]
应该进入demand_init函数的't'和'bus'是索引中的数字和数据框中的列名。它们分别在集合 model.SET_HOURS 和 model.SET_BUSES 中。
我改了方法解决了
您可以将字典传递给 Param 函数,所以我将 demand_init 函数更改为以下内容:
def demand_init(model, data):
init = {}
for t in model.SET_HOURS:
for bus in model.SET_BUSES:
if(bus in set(data.columns)):
init[bus,t] = data.loc[t,bus]
else:
init[bus,t] = 0
return init
然后,我这样定义参数:
INIT_demand = demand_init(model, data = demand)
model.DEMAND = pyo.Param(model.SET_BUSES, model.SET_HOURS, initialize = INIT_demand)
小时集和巴士集都必须预先定义。
我希望这对某人有所帮助。
你似乎已经涵盖了这一点,所以我只是提供一些建议:
只需调用列 1,2 等并调用 轴 bus
,而不是调用每个列 "Bus1"
等
from pyomo import environ as pye
import pandas as pd
import numpy as np
n_bus = 5
n_hours = 10
demand_df = pd.DataFrame(
data = np.random.random(size=(n_hours, n_bus)),
columns = np.arange(1, n_bus+1),
index = np.arange(1, n_hours+1))
demand_df = demand_df.rename_axis('hour', axis=0)
demand_df = demand_df.rename_axis('bus', axis=1)
现在 DataFrame 看起来像
>>> demand_df.head()
bus 1 2 3 4 5
hour
1 0.249303 0.244917 0.348141 0.559970 0.414997
2 0.803017 0.940600 0.474955 0.976134 0.185487
3 0.776821 0.940770 0.482725 0.510914 0.186607
4 0.705604 0.871578 0.154195 0.943887 0.913865
5 0.039853 0.978370 0.320563 0.923042 0.591475
获取字典 {(hour,bus):value}
的简单方法是:
demand_d = demand_df.stack().to_dict()
现在,您似乎想将 0 定义为默认值。共有三种方式(恕我直言,从最坏到最好):
- 使用
defaultdict
:
from collections import defaultdict
demand_d =defaultdict(int, demand_df.stack().to_dict())
- 确保所有列都填满 0 (
.fillna(0)
)
- 定义参数的默认值
model.DEMAND = pyo.Param(
model.SET_BUSES, model.SET_HOURS,
initialize = demand_d,
default = 0)
最后一点,AbstractModel
可能有助于大大减少手动数据摄取的工作量。
第一次使用 pyomo 用户。
我有一个定义模型的函数
def define_problem(SET_gen, SET_time, SET_buses, demand):
model = pyo.ConcreteModel()
#Define sets
model.SET_GEN = pyo.Set(initialize = SET_gen) #Set of generators
model.SET_TIME = pyo.Set(initialize = SET_time) #Set of hours
model.SET_BUSES = pyo.Set(initialize = SET_buses) #Set of buses
#Define parameters
model.DEMAND = pyo.Param(model.SET_BUSES, model.SET_TIME, initialize = demand_init)
...
函数中的参数'demand'是一个pandasDataFrame
函数demand_init定义如下
def demand_init(model, bus, t, data = demand):
if(bus in set(data.columns)):
return data.loc[t,bus]
return 0.0
需要为每个小时和每辆公交车定义参数model.DEMAND作为需求DataFrame中对应的'cell',如果公交车不在DataFrame中则为0。 编辑: 在 define_problem 函数外定义。
但是它不起作用。我如何从 pandas DataFrame 定义函数的参数?
EDIT: Thanks for the answers!
需求数据框如下所示:
Bus1 Bus10 Bus11 Bus12 ... Bus6 Bus7 Bus8 Bus9
Hour ...
1 0.0 9.00 3.50 6.10 ... 11.20 0.0 0.0 29.50
2 0.0 7.34 2.85 4.97 ... 9.13 0.0 0.0 24.06
3 0.0 6.45 2.51 4.37 ... 8.03 0.0 0.0 21.14
4 0.0 5.78 2.25 3.92 ... 7.20 0.0 0.0 18.95
5 0.0 5.56 2.16 3.77 ... 6.92 0.0 0.0 18.22
[5 rows x 14 columns]
应该进入demand_init函数的't'和'bus'是索引中的数字和数据框中的列名。它们分别在集合 model.SET_HOURS 和 model.SET_BUSES 中。
我改了方法解决了
您可以将字典传递给 Param 函数,所以我将 demand_init 函数更改为以下内容:
def demand_init(model, data):
init = {}
for t in model.SET_HOURS:
for bus in model.SET_BUSES:
if(bus in set(data.columns)):
init[bus,t] = data.loc[t,bus]
else:
init[bus,t] = 0
return init
然后,我这样定义参数:
INIT_demand = demand_init(model, data = demand)
model.DEMAND = pyo.Param(model.SET_BUSES, model.SET_HOURS, initialize = INIT_demand)
小时集和巴士集都必须预先定义。
我希望这对某人有所帮助。
你似乎已经涵盖了这一点,所以我只是提供一些建议:
只需调用列 1,2 等并调用 轴 bus
,而不是调用每个列 "Bus1"
等
from pyomo import environ as pye
import pandas as pd
import numpy as np
n_bus = 5
n_hours = 10
demand_df = pd.DataFrame(
data = np.random.random(size=(n_hours, n_bus)),
columns = np.arange(1, n_bus+1),
index = np.arange(1, n_hours+1))
demand_df = demand_df.rename_axis('hour', axis=0)
demand_df = demand_df.rename_axis('bus', axis=1)
现在 DataFrame 看起来像
>>> demand_df.head()
bus 1 2 3 4 5
hour
1 0.249303 0.244917 0.348141 0.559970 0.414997
2 0.803017 0.940600 0.474955 0.976134 0.185487
3 0.776821 0.940770 0.482725 0.510914 0.186607
4 0.705604 0.871578 0.154195 0.943887 0.913865
5 0.039853 0.978370 0.320563 0.923042 0.591475
获取字典 {(hour,bus):value}
的简单方法是:
demand_d = demand_df.stack().to_dict()
现在,您似乎想将 0 定义为默认值。共有三种方式(恕我直言,从最坏到最好):
- 使用
defaultdict
:
from collections import defaultdict
demand_d =defaultdict(int, demand_df.stack().to_dict())
- 确保所有列都填满 0 (
.fillna(0)
) - 定义参数的默认值
model.DEMAND = pyo.Param(
model.SET_BUSES, model.SET_HOURS,
initialize = demand_d,
default = 0)
最后一点,AbstractModel
可能有助于大大减少手动数据摄取的工作量。