I’m currently storing my Pyomo variables in a Pandas dataframe, and have been using that to generate arrays of constraints.
Is there a way I can add them to my model (e.g. by initialising a ConstraintList with it) rather than having to loop through them all and add them individually? I don’t think I’m able to use a rule to create the constraints because I’m indexing based on my Pandas dataframe.
This is how I’m storing my variables – I’m using Pandas because I find it really easy to index by values in my dataframe:
model.duid_bids = pe.Var(bid_df['DUID_BAND_DATETIME'], domain=pe.PositiveReals) bid_df['PE_BIDS'] = bid_df['DUID_BAND_DATETIME'].apply(lambda x: model.duid_bids[x])
And I want to do something like this which does not work:
model.bid_volume = pe.Constraint(expr=bid_df['PE_BIDS'] <= bid_df['VOLUME'])
It works if I add them individually like this:
pe.Constraint(expr=bid_df['PE_BIDS'].iloc[0] <= bid_df['VOLUME'].iloc[0])
Thanks so much.
Advertisement
Answer
I think you are trying too hard to push pyomo
into a pandas
box. :). But that is just an opinion. I don’t see much advantage to doing this because you are not “vectorizing” any operations here as pyomo
constraint construction isn’t vectorized.
I would suggest (others may differ) just doing the optimization in pyomo
without putting any components into the df, but pulling constants out as needed for constraints. Jury is out on whether I’d put the index set you are using into a pyomo Set
, which I think makes things easier to T/S, and pyomo
is going to make a virtual set(s) internally anyhow that you can see in the first example below, but that is a side story.
Here are 2 cuts at your construct that I think are workable and disentangle a bit from pandas
. This assumes that the datetime
you have in your df is unique and can be made into the index for simplicity. (Actually it has to be unique as you are already using it as an indexing set…answered my own question)
import pyomo.environ as pe import pandas as pd data = {'DATETIME': [1,2,3], 'VOLUME': [1000, 2000, 3000]} df = pd.DataFrame(data) df.set_index('DATETIME', inplace=True) print(df.head()) # quick check... model = pe.ConcreteModel() model.duid_bids = pe.Var(df.index, domain=pe.PositiveReals) # volume constraint def vol_constraint(m, date): return model.duid_bids[date] <= df['VOLUME'].loc[date] model.vol_constraint = pe.Constraint(df.index, rule=vol_constraint) model.pprint() ############ alternate approach: full pyomo... ? model2 = pe.ConcreteModel() # sets model2.D = pe.Set(initialize=df.index) # vars model2.bid = pe.Var(model2.D, domain=pe.PositiveReals) # constraint def vol_constraint2(m, date): return model2.bid[date] <= df['VOLUME'][date] model2.vol_constraint = pe.Constraint(model2.D, rule=vol_constraint2) model2.pprint() model2.obj = pe.Objective(expr=sum(model2.bid[date] for date in model2.D), sense=pe.maximize) solver = pe.SolverFactory('glpk') status = solver.solve(model2) print(status) # stuff the result into the dataframe df['bid'] = pd.Series(model2.bid.get_values()) print(df)
Generates:
VOLUME DATETIME 1 1000 2 2000 3 3000 2 Set Declarations duid_bids_index : Size=1, Index=None, Ordered=False Key : Dimen : Domain : Size : Members None : 1 : Any : 3 : {1, 2, 3} vol_constraint_index : Size=1, Index=None, Ordered=False Key : Dimen : Domain : Size : Members None : 1 : Any : 3 : {1, 2, 3} 1 Var Declarations duid_bids : Size=3, Index=duid_bids_index Key : Lower : Value : Upper : Fixed : Stale : Domain 1 : 0 : None : None : False : True : PositiveReals 2 : 0 : None : None : False : True : PositiveReals 3 : 0 : None : None : False : True : PositiveReals 1 Constraint Declarations vol_constraint : Size=3, Index=vol_constraint_index, Active=True Key : Lower : Body : Upper : Active 1 : -Inf : duid_bids[1] : 1000.0 : True 2 : -Inf : duid_bids[2] : 2000.0 : True 3 : -Inf : duid_bids[3] : 3000.0 : True 4 Declarations: duid_bids_index duid_bids vol_constraint_index vol_constraint
model2 separated for clarity…
1 Set Declarations D : Size=1, Index=None, Ordered=Insertion Key : Dimen : Domain : Size : Members None : 1 : Any : 3 : {1, 2, 3} 1 Var Declarations bid : Size=3, Index=D Key : Lower : Value : Upper : Fixed : Stale : Domain 1 : 0 : None : None : False : True : PositiveReals 2 : 0 : None : None : False : True : PositiveReals 3 : 0 : None : None : False : True : PositiveReals 1 Constraint Declarations vol_constraint : Size=3, Index=D, Active=True Key : Lower : Body : Upper : Active 1 : -Inf : bid[1] : 1000.0 : True 2 : -Inf : bid[2] : 2000.0 : True 3 : -Inf : bid[3] : 3000.0 : True 3 Declarations: D bid vol_constraint Problem: - Name: unknown Lower bound: 6000.0 Upper bound: 6000.0 Number of objectives: 1 Number of constraints: 4 Number of variables: 4 Number of nonzeros: 4 Sense: maximize Solver: - Status: ok Termination condition: optimal Statistics: Branch and bound: Number of bounded subproblems: 0 Number of created subproblems: 0 Error rc: 0 Time: 0.010575056076049805 Solution: - number of solutions: 0 number of solutions displayed: 0 VOLUME bid DATETIME 1 1000 1000.0 2 2000 2000.0 3 3000 3000.0