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

Python for循环操作pandas DataFrame时触发KeyError 197报错

报错根因

你贴出的5行测试样例运行不会触发报错,因为测试样例生成后行索引是默认的从0开始连续递增的整数,和range(df_CT.shape[0])生成的循环变量i完全匹配。
实际运行触发KeyError: 197的核心原因是:你业务代码里的df_CT在执行这段循环前,已经做过行删除、过滤、拼接、去重等操作,pandas默认不会自动重置行索引,导致索引不再是连续的0到n-1的整数序列,存在数值断层。而df.loc[索引标签, 列名]是按索引标签精确匹配查找行,当循环生成的i=197刚好是索引序列里不存在的标签时,就会抛出KeyError。
你调试时直接传入具体值能正常运行,是因为你传入的i值刚好是索引里实际存在的标签,自然不会触发报错。

复现验证

我们可以通过模拟索引断层的场景复现这个报错:

import pandas as pd

d = {'Customer Type': ['physician/doctor/gp', 'private hospital', 'private hospital', 'private hospital', 'pharmacy-retail'],
     'Invoice Date Month J&J': ['Oct', 'May', 'Oct', 'Nov', 'May'], 
     'Invoice Date Year J&J': [2015.0, 2016.0, 2016.0, 2017.0, 2018.0], 
     'Matching Type': ['Credit/Other', 'Credit/Other', 'Credit/Other', 'Credit/Other', 'Credit/Other']}

df_CT = pd.DataFrame(data=d)
# 模拟预处理操作:删除索引为2的行,不重置索引
df_CT = df_CT.drop(2)
print(df_CT.index) # 输出 Int64Index([0, 1, 3, 4], dtype='int64'),索引中不存在2

hosp = ['hospital', 'hosp', 'hosps','hospitals', 'hsp','clinics',
        'clinic','clin',"hosp'tl", 'health', 'doctor', 'pract', 'clinical','patients',
       'hlthcare','nurse', 'clncal', 'cln', 'doctors', 'clin','hlth', 'nursing']

# 循环到i=2时就会触发KeyError: 2
for i in range(df_CT.shape[0]):
    if (any(j in df_CT.loc[i,'Customer Type'] for j in hosp)):
        df_CT.loc[i,'CustomerType_Level0'] = 'Hospitals'
修复方案

你可以根据自己的使用场景选以下任意一种方案修复:

  • 方案1:循环前重置索引,最贴合你原有代码逻辑
    在for循环前加一行代码重置索引,丢弃原有断层的索引标签,重新生成从0开始的连续整数索引:
    df_CT = df_CT.reset_index(drop=True)
    
  • 方案2:用pandas原生向量化操作替代逐行for循环,性能最优
    逐行循环在数据量大时运行效率极低,用pandas内置的字符串匹配方法可以避免索引问题,同时运行速度能提升几十到上百倍:
    # 初始化目标列
    df_CT['CustomerType_Level0'] = None
    # 拼接关键词为正则表达式,批量匹配赋值
    match_mask = df_CT['Customer Type'].str.contains('|'.join(hosp))
    df_CT.loc[match_mask, 'CustomerType_Level0'] = 'Hospitals'
    
  • 方案3:逐行遍历时直接取行索引,不要自行生成连续整数序列
    如果一定要保留逐行处理的逻辑,用iterrows()直接获取每行的实际索引和内容,避免手动生成的i和实际索引不匹配:
    for idx, row in df_CT.iterrows():
        if any(j in row['Customer Type'] for j in hosp):
            df_CT.loc[idx, 'CustomerType_Level0'] = 'Hospitals'
    

注意:loc是按索引标签查找,不是按行的物理位置查找,如果需要按行的位置序号取数,应该使用iloc,但日常处理中更推荐前两种方案,代码更简洁也不容易出边界问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 12:54:27