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

Python竞价逻辑模拟报错:索引越界问题求解(If/While循环)

竞价匹配逻辑修复方案

问题根源

你的代码触发single positional indexer is out-of-bounds的原因很明确:

  • 处理单个需求时,找不到符合demand_price > supply_price的供应时,s_row会一直递增直到超出DataFrame的索引范围
  • 原逻辑只单向往下遍历供应,完全没考虑前面行还剩有可匹配的剩余供应量(比如你说的索引3的19单位剩余)

修复思路

核心是给s_row加重置机制,同时优化遍历逻辑:

  1. 每次处理新需求时,从上次暂停的s_row位置开始遍历
  2. 若遍历到供应列表末尾仍无匹配,重置s_row为0,再从头检查一遍剩余供应
  3. 加索引边界判断,防止越界
  4. 只有当当前供应的剩余量为0时,才移动s_row

修复后代码示例

假设你的原始DataFrame定义是类似这样的:

import pandas as pd

# 示例需求表:已按竞价优先级排序(排名越低越靠前)
demand = pd.DataFrame({
    'demand_id': [1,2,3,10],
    'demand_price': [100, 90, 80, 95],
    'quantity': [5, 10, 15, 20]
})

# 示例供应表:已按竞价优先级排序
supply = pd.DataFrame({
    'supply_id': [1,2,3,4],
    'supply_price': [85, 92, 70, 93],
    'quantity': [10, 5, 20, 15]
})

修改后的匹配逻辑代码:

# 初始化索引
d_row = 0
s_row = 0
total_supply_rows = len(supply)
matches = []

while d_row < len(demand):
    current_demand = demand.iloc[d_row]
    # 若当前需求已满足,处理下一个需求
    if current_demand['quantity'] <= 0:
        d_row += 1
        continue
    
    matched = False
    start_row = s_row
    # 最多遍历两轮:一轮从当前位置到末尾,一轮从头开始到当前位置
    for _ in range(2):
        while s_row < total_supply_rows:
            current_supply = supply.iloc[s_row]
            # 检查供应剩余量和价格条件
            if current_supply['quantity'] > 0 and current_demand['demand_price'] > current_supply['supply_price']:
                # 计算可交易的数量:取需求剩余和供应剩余的最小值
                trade_qty = min(current_demand['quantity'], current_supply['quantity'])
                # 记录匹配
                matches.append({
                    'demand_id': current_demand['demand_id'],
                    'supply_id': current_supply['supply_id'],
                    'trade_qty': trade_qty,
                    'demand_price': current_demand['demand_price'],
                    'supply_price': current_supply['supply_price']
                })
                # 更新剩余量
                demand.loc[d_row, 'quantity'] -= trade_qty
                supply.loc[s_row, 'quantity'] -= trade_qty
                matched = True
                # 若供应还剩,不移动s_row,继续用当前供应匹配剩余需求
                if supply.loc[s_row, 'quantity'] > 0:
                    break
                # 供应用完,移动到下一个
                else:
                    s_row += 1
                    break
            else:
                # 当前供应不满足,移动到下一个
                s_row += 1
        # 第一轮遍历完没找到,重置s_row到0,再找一次
        if not matched:
            s_row = 0
        else:
            break
    
    # 两轮遍历都没找到匹配,处理下一个需求
    if not matched:
        d_row += 1
        s_row = 0

# 输出匹配结果
print(pd.DataFrame(matches))

关键改动说明

  • 双轮遍历机制:先从上次停止的位置找供应,找不到就重置到0再找一遍,确保不会漏掉前面的剩余供应
  • 供应剩余量判断:只有当当前供应的剩余量为0时,才移动s_row,否则继续用该供应匹配当前需求的剩余量
  • 边界防护:所有s_row的操作都有s_row < total_supply_rows的判断,完全避免索引越界
  • 需求处理逻辑:当前需求剩余量为0时,才切换到下一个需求,同时保留当前s_row位置(因为可能还有剩余供应能匹配下一个需求)

验证你的场景

针对你提到的索引3剩余19单位供应匹配索引10需求的场景:

  • 处理索引10的需求时,若第一轮从当前s_row位置没找到,会重置到0,遍历到索引3的供应,发现价格满足且有剩余量,就会完成匹配

内容的提问来源于stack exchange,提问作者Lina Antelmann

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 00:53:32