【问题标题】:Pyomo DataPortal Not Working with Multiple Indices (Abstract Model, CSV Import)Pyomo DataPortal 不使用多个索引(抽象模型,CSV 导入)
【发布时间】:2021-12-23 06:32:39
【问题描述】:

我正在尝试使用 Pyomo 中的 DataPortal 设置为抽象模型导入 CSV 数据。

from pyomo.environ import *
model = AbstractModel()
model.t = Set()  # year index
model.a = Set()  # type of resource index
model.q = Set()  # zone index
model.EERF = Param(model.a, model.q, model.t)  # feedstock production

data = DataPortal()
data.load(filename='EERBiomassProd.csv', param=model.EERF, index=(model.t, model.q, model.a))
instance = model.create_instance(data)

我要从中导入的 CSV 有四列,多行。

year zone source tons
2020 california herbaceous 2
2020 california waste 4
... ... ... ...
2050 utah/nevada woody 900

共有 4 个年份值、10 个区域和 3 个来源。我希望这些都是我的参数的索引,参数的值设置为“吨”列。

当我运行我的代码时,我从 Python 收到以下错误。

RuntimeError: Failed to set value for param=EERF, index=(2020, 'california', 'herbaceous'), value=2.
    source error message=unsupported operand type(s) for +: 'int' and 'type'

建议?我可以尝试以其他方式导入数据,例如使用 Pandas 数据框吗?我是否应该手动写出每个索引的内容,而不是尝试使用 DataPortal 从 CSV 中读取它们(例如,model.t = Set(initialize=[2020, 2030, 2040, 2050]))?

【问题讨论】:

  • EERBiomassProd.csv 在某处可用吗?
  • 我已将我的工作目录设置为存储 csv 的位置,如果这是您所要求的,那么 Python 访问 CSV 没有问题。我展示了上面的 CSV 结构。
  • 是的,问题不存在。我在问你是否介意分享你的文件。因此,有人可以尝试复制您的问题
  • 抱歉,我是 Stack Overflow 的新手。有推荐的文件共享方式吗?我好像不能上传文件。
  • 没关系。无需共享您的文件。刚刚尝试过,即使使用您提到的 3 行,也会出现问题。 (PS:欢迎来到stackoverflow!)

标签: python csv pyomo


【解决方案1】:

我觉得你是在找麻烦... :)

您在读取这样的数据时遇到的问题是从多维集合到单个集合的推论。我不认为pyomo 可以自然地做到这一点。您可能可以从 3-dim 索引中折磨出各个集合,但可能不值得。您将遇到pyomo 必须解决的重复问题等问题。索引中可能存在许多重复项(2020 年将多次出现,加利福尼亚州等地也是如此)。

下面的第一个示例读取您的数据(使用下面发布的类似 .csv),但只能捕获 3-dim 索引。也许这“足够好”但不太可能。

如果您想留在“抽象领域”,您可能应该将您的集合分解为单独的数据字段/文件等,可能在文档中使用 JSON 或 YAML 结构。

选项 2 是使用 csv readerpandas 或本地开发的东西来读取 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

【讨论】:

  • 感谢分享。在加载电子表格之前,我可以通过提前设置每个索引(例如,model.t = Set(initialize=[2020, 2030, 2040, 2050]))来消除我的错误。只要我提前指定索引,将三个索引分开是否仍然存在问题,还是我每次都必须创建一个 3-dim 索引?我的完整模型有大约 15 个参数,每个参数都有 1 到 5 个索引,所以我想尽可能避免创建多个新的多维度索引(这就是为什么我编写它以三个单独的索引进行索引)。
  • 所以你有某种“混合”具体/抽象模型......好吧。是的,您当然可以尝试将 1-dim 索引分开。您必须为稀疏索引的参数提供默认值。当您开始处理变量时,您可能会回过头来并希望以某种方式捕获“有效”索引,所以直到那时!如果以上回答了您的问题,请点击“检查”关闭问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-06-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-29
  • 2022-01-21
  • 2020-10-03
相关资源
最近更新 更多