1

I would like to display all the results of Pyomo variables in a pandas dataframe. I had a look at this question Pyomo: Looping Over A Variable Method and tried to adjust it to my case without success. I always get error messages. Here is a part of my code:

model.set_timeslots = pyo.RangeSet(1, 288)
iterables = list (range (1, 288))
...
...
...
for v in model.component_objects(pyo.Var, active=True):
    for index in v:
        print(index, ': ', pyo.value(v[index]))

DF = pd.DataFrame(index=iterables) for v in model.component_objects(pyo.Var, active=True): for index in v: DF.at[index, 'val'] = pyo.value(v[index])

So I would like to print each value of the variables for all 288 set values for the set model.set_timeslots. Further, I also have some variables that do not depend on a set (for example objective variables). I would also like them to be displayed in a pandas dataframe. Do you know how I can do that? I'd appreciate every comment and would be quite thankful for your help.

Reminder: Does nobody have an idea how I can do that?

PeterBe
  • 1,632
  • 2
  • 15
  • 30
  • Would you try using this or this as offered by Pyomo? I hope they will be helpful. :) – A.Omidi Apr 20 '21 at 10:40
  • Thanks for your comment A.Omidi. So shall I not ask questions about Pyomo in the Operations Research channel? I have seen quite many questions about Pyomo here. – PeterBe Apr 20 '21 at 11:51
  • OR.SE is an optimization forum and actually, you can ask your related questions here. What I mentioned is two useful links offered by Pyomo developers in its host. You might get the answer to your technical questions there a bit quickly – A.Omidi Apr 20 '21 at 19:31

1 Answers1

2

I don't know your entire code or the errors you get, but the general way is

optimal_values = [value(model.x[key]) for key in model.x]
df = pd.DataFrame(optimal_values)

where

model.x

is your target variable that is optimized.

Steven01123581321
  • 1,043
  • 6
  • 12
  • Thanks Steven for your answer. Unfortunately I get an error message when using your suggested code optimal_values = [value(model.variable_heatGenerationCoefficient_SpaceHeating[key]) for key in model.variable_heatGenerationCoefficient_SpaceHeating] df = pd.DataFrame(model.variable_heatGenerationCoefficient_SpaceHeating) stating "NameError: name 'value' is not defined". – PeterBe Apr 21 '21 at 09:32
  • Further, I have quite many variables in my model (about 30). Is there no way how I can just get the values for all of them together e.g. via a loop? With your approach I would have to specify this for each of the 30 variables which is quite time consuming – PeterBe Apr 21 '21 at 09:33
  • your second question: yes ofc, you can put all the variables in a list and then loop over the list (e.g. for model in model_list). I don't get why you get that name error (has something to do with your variable), maybe it's good to share you entire code or at least the crucial parts. – Steven01123581321 Apr 21 '21 at 09:40
  • Thanks Steven for your answer. How would the loop look like? – PeterBe Apr 21 '21 at 10:19
  • Here my variable definitons of 2 variables: model.variable_heatGenerationCoefficient_SpaceHeating = pyo.Var(model.set_timeslots, bounds=(0,1)) model.variable_heatGenerationCoefficient_DHW = pyo.Var(model.set_timeslots, bounds=(0,1)) So let's say I would like to see the values for the model.variable_heatGenerationCoefficient_SpaceHeating I used your suggested code optimal_values = [value(model.variable_heatGenerationCoefficient_SpaceHeating[key]) for key in model.variable_heatGenerationCoefficient_SpaceHeating] df = pd.DataFrame(model.variable_heatGenerationCoefficient_SpaceHeating) – PeterBe Apr 21 '21 at 10:22
  • model_list = [variable_heatGenerationCoefficient_SpaceHeating, variable_heatGenerationCoefficient_DHW] and then something like optimal_values_list = [[value(model.model_item[key]) for key in model.model_item] for model_item in model_list] and then you get a list of seperate lists, which you can then assign to columns in a dataframe. For your name error, I suggest you try 'from pyomo.environ import value', because you need to explicitly import it. – Steven01123581321 Apr 21 '21 at 11:52
  • Thanks Steven for your answer and effort. I really appreciate it. I now do not get the name error any more when using optimal_values = [pyo.value(model.variable_heatGenerationCoefficient_SpaceHeating[key]) for key in model.variable_heatGenerationCoefficient_SpaceHeating] df = pd.DataFrame(model.variable_heatGenerationCoefficient_SpaceHeating). HOWEVER, the dataframe df does not show the corret values for the model.variable_heatGenerationCoefficient_SpaceHeating. It just shows the values of the set the variable is based on but not the resulting values – PeterBe Apr 21 '21 at 15:02
  • df = pd.DataFrame(optimal_values) and not df = pd.DataFrame(model.variable_heatGenerationCoefficient_SpaceHeating). Does this help? – Steven01123581321 Apr 21 '21 at 17:50
  • That was a mistake in my original answer. – Steven01123581321 Apr 21 '21 at 18:42
  • Thanks Steven for your answer and effort. I really appreciate it. Basically now for 1 variable it works but your suggested code when having multiple variables does not work. I used the following code as suggested by you: outputVariables_list = [model.variable_heatGenerationCoefficient_SpaceHeating, model.variable_heatGenerationCoefficient_DHW] optimal_values_list = [[pyo.value(model.model_item[key]) for key in model.model_item] for model.model_item in outputVariables_list] df = pd.DataFrame(optimal_values_list) – PeterBe Apr 22 '21 at 07:23
  • And I get the error: "RuntimeError: Attempting to re-assign the component 'variable_heatGenerationCoefficient_SpaceHeating' to the same block under a different name (model_item).

    This behavior is not supported by Pyomo; components must have a single owning block (or model), and a component may not appear multiple times in a block. If you want to re-name or move this component, use the block del_component() and add_component() methods"

    – PeterBe Apr 22 '21 at 07:23
  • 1
    I don't know what they mean with that error, but the part "for model.model_item in outputVariablesList" should be "for model_item in outputVariablesList" – Steven01123581321 Apr 22 '21 at 07:35
  • Thanks a lot Steven for your further comment. Yes now it works. Maybe 2 small follow-up questions that are not so important: 1) At the moment the variables are inserted as rows. Is it possible to insert them as columns? 2) Can I also include the names of the variables in the columns or rows in the dataframe? – PeterBe Apr 22 '21 at 07:47
  • Thanks Steven for your answer and effort. I really appreciate it. I tried what you suggested but it did not change much. The data of each variable is till in the row and not in the column and there are also no column/row names visible. Here is my code: outputVariables_list = [model.variable_heatGenerationCoefficient_SpaceHeating, model.variable_heatGenerationCoefficient_DHW] optimal_values_list = [[pyo.value(model_item[key]) for key in model_item] for model_item in outputVariables_list] df = pd.DataFrame(columns=optimal_values_list) – PeterBe Apr 22 '21 at 09:21
  • When using df = pd.DataFrame(optimal_values_list) the output is just a dataframe with 3 rows and 288 columns. The first column looks like this "Index; 0; 1" and the first row looks like this "Index; 0; 1; 2, ..., 288". When using df = pd.DataFrame(columns=optimal_values_list) the first column looks like this "Index 0, None, None" and the first row looks like "Index 0; 0; 1; 2, ..., 288". In both cases the values of the variables are just inserted in the rows. So each variables creates a new rows and its 287 values are displayed horizontally – PeterBe Apr 22 '21 at 09:30
  • 1
    Thanks a lot Steven for your tremendous help and effort. It helped a lot. I upvoted and accepted your answer – PeterBe Apr 22 '21 at 15:53