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

多日期结算周期机组发电量模拟函数故障:输出重复需修正

解决分日期分结算周期的机组发电量模拟结果重复问题

问题核心

基于merit_order(机组优先级)、total_fossil_demand(多日期分结算周期的化石燃料需求)、Max_cumulative_generation(按优先级累积的机组最大发电量上限)三个Pandas DataFrame开发的模拟函数,目前所有日期的发电量输出完全重复,无法实现按日期+结算周期维度的独立计算。

问题根源

函数未针对日期+结算周期的组合维度做分组处理,而是全局套用同一套计算逻辑,导致所有日期复用了同一周期的计算结果。

解决方案:按分组维度重构计算逻辑

通过groupby(['日期', '结算周期'])对数据做分组,让每个分组独立执行发电量分配规则,确保不同日期、不同结算周期的结果互不干扰。

步骤1:核心单周期计算函数

先实现针对单个(日期+结算周期)分组的发电量计算逻辑:

import pandas as pd

def calculate_single_period_dispatch(demand_series, period_merit_order, period_max_cumulative):
    """
    计算单个日期+结算周期的机组发电量
    参数:
        demand_series: 单周期的化石燃料需求(带(日期,结算周期)索引的Series)
        period_merit_order: 当前结算周期的机组优先级DataFrame
        period_max_cumulative: 当前日期+结算周期的累积发电量上限DataFrame
    返回:
        该周期的各机组发电量DataFrame
    """
    # 按优先级排序机组(确保和merit_order定义一致)
    sorted_units = period_merit_order.sort_values("优先级", ascending=True).reset_index(drop=True)
    remaining_demand = demand_series["total_fossil_demand"]
    dispatch_records = []
    current_date, current_period = demand_series.name

    for _, unit in sorted_units.iterrows():
        unit_id = unit["机组ID"]
        unit_max_gen = unit["单机最大发电量"]
        # 获取该机组当前周期的累积发电量上限
        cum_max = period_max_cumulative.loc[
            period_max_cumulative["机组ID"] == unit_id,
            "Max_cumulative_generation"
        ].values[0]
        
        # 分配发电量:取剩余需求、单机上限、累积上限三者最小值
        gen_amount = min(remaining_demand, unit_max_gen, cum_max)
        dispatch_records.append({
            "日期": current_date,
            "结算周期": current_period,
            "机组ID": unit_id,
            "发电量": gen_amount
        })
        
        remaining_demand -= gen_amount
        # 需求耗尽时,剩余机组发电量设为0
        if remaining_demand <= 0:
            remaining_units = sorted_units.iloc[_+1:]
            for _, ru in remaining_units.iterrows():
                dispatch_records.append({
                    "日期": current_date,
                    "结算周期": current_period,
                    "机组ID": ru["机组ID"],
                    "发电量": 0
                })
            break
    
    return pd.DataFrame(dispatch_records)

步骤2:分组调用主函数

遍历所有(日期+结算周期)分组,调用核心函数计算并合并结果:

def simulate_full_dispatch(total_fossil_demand, merit_order, max_cumulative_generation):
    """
    全量模拟分日期分结算周期的机组发电量
    参数:
        total_fossil_demand: 含日期、结算周期、total_fossil_demand字段的DataFrame
        merit_order: 含结算周期、机组ID、优先级、单机最大发电量字段的DataFrame
        max_cumulative_generation: 含日期、结算周期、机组ID、Max_cumulative_generation字段的DataFrame
    返回:
        分日期分结算周期的各机组发电量结果DataFrame
    """
    # 按日期+结算周期分组处理需求数据
    grouped_demand = total_fossil_demand.groupby(["日期", "结算周期"])
    all_results = []

    for group_key, demand_group in grouped_demand:
        current_date, current_period = group_key
        # 筛选当前结算周期的机组优先级数据
        period_merit = merit_order[merit_order["结算周期"] == current_period]
        # 筛选当前日期+结算周期的累积发电量上限数据
        period_cum_max = max_cumulative_generation[
            (max_cumulative_generation["日期"] == current_date) &
            (max_cumulative_generation["结算周期"] == current_period)
        ]
        # 计算该分组的发电量
        period_result = calculate_single_period_dispatch(demand_group.squeeze(), period_merit, period_cum_max)
        all_results.append(period_result)
    
    # 合并所有分组结果
    final_result = pd.concat(all_results, ignore_index=True)
    return final_result

验证与期望输出

调用simulate_full_dispatch后,将得到分日期分结算周期的独立结果,示例如下:

日期结算周期机组ID发电量
2024-01-011UC1100
2024-01-011UC280
2024-01-012UC1120
2024-01-021UC190
2024-01-021UC275

注意事项

  1. 确保三个输入DataFrame的字段名与代码中使用的一致,若有差异需对应调整
  2. 若merit_order的优先级规则是全局而非分结算周期,可去掉代码中对结算周期的筛选
  3. 若存在需求为0的情况,需在函数中添加判断,直接返回所有机组发电量为0的结果

内容的提问来源于stack exchange,提问作者Chetan Patel

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 11:10:41