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

Pandas实现两DataFrame部分匹配合并时IndexError报错排查

报错原因定位

报错触发的直接原因是:循环匹配过程中,存在某条Invoice值在df2['Ref']字段中没有任何符合contains匹配规则的记录,此时筛选得到的tmp是空DataFrame,对空结果直接取tmp['Amount'].values[0]相当于从长度为0的数组中取第一个元素,直接抛出索引越界错误。
另外你当前使用的逐行iterrows遍历写法性能极差,你提到df2有62万行数据,这种写法的运行耗时会非常长,完全不适合大数据量场景。

高效实现方案(推荐,适配62万行数据场景)

不要用逐行循环,用向量化的正则提取+等值合并逻辑,运行效率比循环高两个数量级以上,同时自动处理无匹配的场景,不会触发索引报错:

import pandas as pd
import re

# 1. 构造匹配正则,将df1中所有发票号拼接为或匹配模式
inv_pattern = '|'.join(re.escape(inv_num) for inv_num in df1['Invoice'].unique())
# 2. 从df2的Ref字段中提取匹配到的发票号,无匹配则返回空值
df2['match_key'] = df2['Ref'].str.extract(f'({inv_pattern})', expand=False)
# 3. 按匹配到的键做左连接合并,最后删掉临时生成的匹配键列
df_result = df1.merge(
    df2,
    left_on='Invoice',
    right_on='match_key',
    how='left'
).drop(columns=['match_key'])

运行后得到的合并结果和预期完全一致:

Invoice Currency         Ref Type Amount Comment
0   20561      EUR       20561   01    150     bla
1   20562      EUR    INV20562   03    175     bla
2   20563      EUR  INV20563BG   04    160     bla
3   20564      USD       20564   02    180     bla

如果存在某条Invoice在df2中完全匹配不到,对应df2的字段会自动填充为空值,不会触发报错。

原循环逻辑的修正方案(不推荐,仅作参考)

如果一定要保留遍历写法,必须在取值前判断匹配结果是否为空,避免取空数组的元素:

df4 = df1.copy()
for i, row in df1.iterrows():
    match_res = df2[df2['Ref'].str.contains(row['Invoice'], na=False)]
    # 先判断是否存在匹配结果再赋值
    if len(match_res) > 0:
        df4.loc[i, 'Amount'] = match_res['Amount'].iloc[0]
    else:
        df4.loc[i, 'Amount'] = pd.NA

注意:这个方案仅适合极小数据量场景,62万行数据下运行速度会非常慢,优先使用前面的向量化合并方案。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 21:24:31