Как я могу экспортировать результаты из переменной Pyomo в Pandas фрейм данных и в Excel? - PullRequest
0 голосов
/ 10 марта 2020

У меня есть несколько переменных Pyomo в модели, некоторые с тремя индексами. Для объяснения, одна из моих переменных -

model.E_grid = Var(model.i, model.m, model.p, within = NonNegativeReals)

, а три индекса - это i, m и p. После запуска модели я хотел бы видеть окончательные значения E_grid относительно каждого i, m и p в pandas фрейме данных (что затем позволит мне экспортировать его в excel). Так, например, что-то вроде [i1, m1, p1, 21.00], [i1, m1, p2, 22.00] и так далее. Я уже видел метод "блок", который пытается экспортировать все переменные в один go (например, https://or.stackexchange.com/questions/2708/pyomo-looping-over-a-variable-method), но он не работает для меня, потому что некоторые переменные имеют только 1 индекс , Любая помощь с этим будет высоко ценится!

Редактировать: это именно то, что я пытался

results_df = pd.DataFrame()
for v in model.component_objects(model.E_grid, active=True):
    for i, m, p in v:
        results_df.at[i,m,p, v.name] = value(v[i,m,p])

print(results_df) 

Но я получаю ошибку ValueError: Недостаточно индексов для скалярного доступа ( настройка)!

1 Ответ

0 голосов
/ 17 марта 2020

Первый аргумент component_objects() должен быть типом компонента (например, Var), а не компонентом (ie model.E_grid). Вы можете использовать .items() для итерации по IndexedComponent.

Во-вторых, ошибка, которую вы видите, происходит из-за способа индексации кадра данных и установки значения на лету. Если вы просто хотите построить фрейм данных из значений переменных, может быть гораздо проще просто использовать dict-понимание и затем один из pandas 'конструкторов фреймов данных:

import pandas as pd
from pyomo.core import ConcreteModel, Set, NonNegativeReals, Var, value

model = ConcreteModel()
model.i = Set(initialize=[1, 2, 3])
model.m = Set(initialize=[4, 5, 6])
model.p = Set(initialize=[7, 8, 9])

model.E_grid = Var(model.i, model.m, model.p, within=NonNegativeReals, initialize=1)

E_grid_data = {(i, m, p, v.name): value(v) for (i, m, p), v in model.E_grid.items()}
df = pd.DataFrame.from_dict(E_grid_data, orient="index", columns=["variable value"])
print(df)
#                           variable value
# (1, 4, 7, E_grid[1,4,7])               1
# (1, 4, 8, E_grid[1,4,8])               1
# (1, 4, 9, E_grid[1,4,9])               1
# (1, 5, 7, E_grid[1,5,7])               1
# (1, 5, 8, E_grid[1,5,8])               1
# (1, 5, 9, E_grid[1,5,9])               1

Теперь вы можете выполнить постобработку фрейм данных, если вы хотите разделить индекс на мультииндекс.

...