我觉得你是在找麻烦... :)
您在读取这样的数据时遇到的问题是从多维集合到单个集合的推论。我不认为pyomo 可以自然地做到这一点。您可能可以从 3-dim 索引中折磨出各个集合,但可能不值得。您将遇到pyomo 必须解决的重复问题等问题。索引中可能存在许多重复项(2020 年将多次出现,加利福尼亚州等地也是如此)。
下面的第一个示例读取您的数据(使用下面发布的类似 .csv),但只能捕获 3-dim 索引。也许这“足够好”但不太可能。
如果您想留在“抽象领域”,您可能应该将您的集合分解为单独的数据字段/文件等,可能在文档中使用 JSON 或 YAML 结构。
选项 2 是使用 csv reader 或 pandas 或本地开发的东西来读取 pyomo 之外的数据,然后从结果中创建一个 ConcreteModel。这是示例中的m2。我认为这是最简单的?取决于模型的其余部分...
数据.csv:
year,zone,source,tons
2020,ca,herb,2
2020,ca,waste,3
2020,nv,waste,4
2019,az,herb,5
脚本:
from pyomo.environ import *
model = AbstractModel()
# model.t = Set() # year index
# model.a = Set() # type of resource index
# model.q = Set() # zone index
model.tqa = Set(dimen=3)
model.EERF = Param(model.tqa) # feedstock production
data = DataPortal()
data.load(filename='data.csv', param=model.EERF, index=model.tqa)
instance = model.create_instance(data)
instance.pprint()
### Option 2 ###
import pandas as pd
df = pd.read_csv('data.csv').set_index(['year', 'zone', 'source'])
model_data = df.to_dict('index')
m2 = ConcreteModel('pandas_based')
### SETS
# note: sorted lists from sets is required to (1) avoid dupes,
# and (2) provide lists to initializer for consistent
# (deterministic) results. Failure to do either will gen warnings...
m2.t = Set(initialize=sorted({t[0] for t in model_data.keys()}))
m2.q = Set(initialize=sorted({t[1] for t in model_data.keys()}))
m2.a = Set(initialize=sorted({t[2] for t in model_data.keys()}))
# a convenience for later use...
m2.tqa_idx = Set(within=m2.t*m2.q*m2.a, initialize=model_data.keys())
### PARAMS
m2.EERF = Param(m2.t, m2.q, m2.a, initialize=
{t[0]:t[1]['tons'] for t in model_data.items()})
print(' *** Concrete Model *** ')
m2.pprint()
输出:
1 Set Declarations
tqa : Size=1, Index=None, Ordered=Insertion
Key : Dimen : Domain : Size : Members
None : 3 : Any : 4 : {(2020, 'ca', 'herb'), (2020, 'ca', 'waste'), (2020, 'nv', 'waste'), (2019, 'az', 'herb')}
1 Param Declarations
EERF : Size=4, Index=tqa, Domain=Any, Default=None, Mutable=False
Key : Value
(2019, 'az', 'herb') : 5
(2020, 'ca', 'herb') : 2
(2020, 'ca', 'waste') : 3
(2020, 'nv', 'waste') : 4
2 Declarations: tqa EERF
*** Concrete Model ***
7 Set Declarations
EERF_index : Size=1, Index=None, Ordered=True
Key : Dimen : Domain : Size : Members
None : 3 : t*q*a : 12 : {(2019, 'az', 'herb'), (2019, 'az', 'waste'), (2019, 'ca', 'herb'), (2019, 'ca', 'waste'), (2019, 'nv', 'herb'), (2019, 'nv', 'waste'), (2020, 'az', 'herb'), (2020, 'az', 'waste'), (2020, 'ca', 'herb'), (2020, 'ca', 'waste'), (2020, 'nv', 'herb'), (2020, 'nv', 'waste')}
a : Size=1, Index=None, Ordered=Insertion
Key : Dimen : Domain : Size : Members
None : 1 : Any : 2 : {'herb', 'waste'}
q : Size=1, Index=None, Ordered=Insertion
Key : Dimen : Domain : Size : Members
None : 1 : Any : 3 : {'az', 'ca', 'nv'}
t : Size=1, Index=None, Ordered=Insertion
Key : Dimen : Domain : Size : Members
None : 1 : Any : 2 : {2019, 2020}
tqa_idx : Size=1, Index=None, Ordered=Insertion
Key : Dimen : Domain : Size : Members
None : 3 : tqa_idx_domain : 4 : {(2020, 'ca', 'herb'), (2020, 'ca', 'waste'), (2020, 'nv', 'waste'), (2019, 'az', 'herb')}
tqa_idx_domain : Size=1, Index=None, Ordered=True
Key : Dimen : Domain : Size : Members
None : 3 : tqa_idx_domain_index_0*a : 12 : {(2019, 'az', 'herb'), (2019, 'az', 'waste'), (2019, 'ca', 'herb'), (2019, 'ca', 'waste'), (2019, 'nv', 'herb'), (2019, 'nv', 'waste'), (2020, 'az', 'herb'), (2020, 'az', 'waste'), (2020, 'ca', 'herb'), (2020, 'ca', 'waste'), (2020, 'nv', 'herb'), (2020, 'nv', 'waste')}
tqa_idx_domain_index_0 : Size=1, Index=None, Ordered=True
Key : Dimen : Domain : Size : Members
None : 2 : t*q : 6 : {(2019, 'az'), (2019, 'ca'), (2019, 'nv'), (2020, 'az'), (2020, 'ca'), (2020, 'nv')}
1 Param Declarations
EERF : Size=4, Index=EERF_index, Domain=Any, Default=None, Mutable=False
Key : Value
(2019, 'az', 'herb') : 5
(2020, 'ca', 'herb') : 2
(2020, 'ca', 'waste') : 3
(2020, 'nv', 'waste') : 4