如何在Python中使用多索引DataFrame改写Pyomo约束?
解决Pyomo约束中多索引DataFrame的索引问题
问题背景
之前用单索引DataFrame(Q1/Q2/Q3)写Pyomo约束时运行正常,但切换为多索引DataFrame dftmax 后出现索引错误:
- 用
dftmax.iloc[t, k, i]触发pandas.errors.IndexingError: Too many indexers - 用
dftmax.loc[(t,k), column_name]触发KeyError: 0
需求是根据k值从dftmax中正确取数,使得k=0时约束为:dft[i, k, t] <= dftmax.iloc[i,0,t](i取0-3,t取0-23)。
错误原因
- iloc参数超量:DataFrame是二维结构,
iloc仅接受「行索引、列索引」两个维度的参数,传三个参数必然报错。 - loc索引不匹配:传入的索引元组和
dftmax的多索引结构不对应(比如误把t当成行索引的一部分,而非列或另一级索引)。
解决方案
根据dftmax的多索引结构(参考提供的结构示意图),选择对应索引方式,以下是两种常见结构的适配代码:
情况1:dftmax行索引为i(0-3),列索引为MultiIndex(k, t)(k=0/1/2,t=0-23)
L_model.constraint_b1 = pyo.ConstraintList() for i in range(len(initial_demand)): for k in range(Nb): for t in demand.index: # 直接通过多索引定位对应值 max_demand = dftmax.loc[i, (k, t)] L_model.constraint_b1.add(dft[i, k, t] <= max_demand)
情况2:dftmax行索引为MultiIndex(i, k),列索引为t(0-23)
L_model.constraint_b1 = pyo.ConstraintList() for i in range(len(initial_demand)): for k in range(Nb): for t in demand.index: # 通过行多索引+列索引定位 max_demand = dftmax.loc[(i, k), t] L_model.constraint_b1.add(dft[i, k, t] <= max_demand)
代码优化说明
- 删掉了原代码里冗余的
bl_inx循环,直接用k值匹配多索引层级,逻辑更简洁。 - 用
loc替代iloc做索引,可读性更强且不易出错(如果必须用整数索引,可先获取对应层级的位置再用iloc)。
内容的提问来源于stack exchange,提问作者Nasim Eslaminia
相关产品推荐
相关产品推荐

