You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Gekko调用Pandas DataFrame数据建模时报数据长度匹配错误

问题说明

尝试将理论模型与历史油市数据对比,计划通过Gekko将多个Pandas DataFrame中存储的实测数据输入模型方程,代码运行时抛出数据长度匹配异常,已检查各DataFrame维度一致但无法定位错误原因。

原实现代码

import pandas as pd
import pylab as plt
import numpy as np
from gekko import GEKKO

#DATA#
#oil supply
data = pd.read_html('https://www.eia.gov/dnav/pet/hist/LeafHandler.ashx?n=pet&s=mcrfpus2&f=m')
s=data[4]
sply = s.loc[s['Year'] >= 1984]
supplyvalues = sply.filter(items = ['Jan', 'Feb', 'Mar', 'Apr', 'May','Jun','Jul','Aug','Sep', 'Oct', 'Nov','Dec'])
val2 = supplyvalues.dropna()
protoval3 = supplyvalues.shift(1)
val3=protoval3.dropna()
#price of oil
p = pd.read_html('https://www.eia.gov/dnav/pet/hist/LeafHandler.ashx?n=PET&s=EMA_EPM0_PTG_NUS_DPG&f=M')
Op=p[4]
prc = Op.loc[Op['Year'] >= 1984]
pricevalues = prc.filter(items = ['Jan', 'Feb', 'Mar', 'Apr', 'May','Jun','Jul','Aug','Sep', 'Oct', 'Nov','Dec'])
val1 = pricevalues.dropna()

#EQUATION#
m=GEKKO()
tm = np.linspace(0,10,50)
t=m.Param(value = tm)
m.time = tm
m.options.IMODE=4

#forming equation
a,b,c = m.Array(m.Param,3)
a.value = val1.values
b.value = val2.values
c.value = val3.values
x = m.Var()
m.Equation(a == c-a*b)
m.solve(disp=False)

触发的异常

Exception: Data arrays must have the same length, and match time discretization in dynamic problems
错误根因
  • 时间离散点长度和输入数据不匹配:代码中硬编码的时间序列tm仅设置了50个时间点,但1984年至今的月度油市数据共有数百个点,Gekko动态模式要求所有输入参数的长度必须和m.time定义的时间点数量完全一致,这是触发报错的直接原因。
  • 数据维度不符合要求:提取的val1/val2/val3是「年份为行、月份为列」的二维宽表,没有展平为Gekko支持的一维时序数组,即使长度匹配也无法正常赋值。
  • 模型逻辑不完整:定义的求解变量x没有出现在方程中,方程仅包含参数,没有待求解的未知量,即使长度问题修复也无法正常求解。
修复方案

按以下步骤调整代码即可解决问题,新增代码附带作用说明:

  1. 首先将二维的月度数据表展平为一维时间序列,对齐三个数据集的公共长度,避免缺省值导致的长度差:
# 将按年-月存储的二维宽表展平为按时间排序的一维数组,同时剔除空值
val1_flat = val1.stack().dropna().values
val2_flat = val2.stack().dropna().values
val3_flat = val3.stack().dropna().values

# 取三个序列的最短公共长度,截断所有序列到该长度,保证长度完全一致
data_len = min(len(val1_flat), len(val2_flat), len(val3_flat))
val1_flat = val1_flat[-data_len:]
val2_flat = val2_flat[-data_len:]
val3_flat = val3_flat[-data_len:]

代码说明:.stack()会把每行的12个月度值按年份先后顺序拼接,得到连续的月度时间序列;截断操作是为了避免滞后处理、空值剔除导致三个序列长度差1-2个点的问题。

  1. 调整Gekko时间序列定义,让时间点数量和输入数据长度完全匹配:
m = GEKKO()
# 时间序列点数和展平后的数据点数量完全一致,不再硬编码50个点
tm = np.linspace(0, data_len-1, data_len)
t = m.Param(value=tm)
m.time = tm
m.options.IMODE = 4

代码说明:动态仿真模式下m.time的长度就是模型的时间步总数,所有时序参数、变量的长度必须和这个值一致。

  1. 修正参数赋值和模型方程,将待求解变量纳入方程:
# 为三个参数赋值对齐后的一维时序数据
a = m.Param(value=val1_flat)
b = m.Param(value=val2_flat)
c = m.Param(value=val3_flat)
# 为求解变量设置初始值,用序列第一个数据点作为初始值
x = m.Var(value=val1_flat[0])
# 替换为实际的理论模型方程,示例为x的动态变化方程,需根据你的理论假设调整
m.Equation(x.dt() == c - a*b)

m.solve(disp=False)

代码说明:原方程a == c-a*b中全是已知参数,不存在待求解的未知量,Gekko无法执行求解;调整后的方程将变量x的变化率和三个输入参数关联,符合动态仿真的逻辑要求,你可以替换为自己推导的理论模型形式。

内容的提问来源于stack exchange,提问作者Ok-Investments

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 07:45:34