邮编掩码处理代码出现KeyError: '0'问题排查求助
问题描述
按Safe Harbor规范更新df_users DataFrame的邮编:若邮编对应地理分区人口≤20000则设为'0',否则保留前3位。编写的循环代码部分功能有效,但运行时出现KeyError: '0'报错。
运行代码
# 遍历DataFrame获取每个邮编 for zipcode in df_users['zip']: # 检查邮编前3位对应的分区人口是否≤20000 if zip_dict[zipcode[:len(zipcode) - 2]] <= 20000: # 人口≤20000时,将邮编设为字符串'0' df_users.loc[df_users['zip'] == zipcode, 'zip'] = '0' else: # 人口>20000时,仅保留邮编前3位 df_users.loc[df_users['zip'] == zipcode, 'zip'] = zipcode[:len(zipcode) - 2]
报错信息
KeyError Traceback (most recent call last) /var/folders/95/4vh4zhc1273fgmfs4wyntxn00000gn/T/ipykernel_44758/1429192050.py in < module > 1 for zipcode in df_users['zip']: ----> 2 if zip_dict[zipcode[:len(zipcode) - 2]] <= 20000: 3 df_users.loc[df_users['zip'] == zipcode, 'zip'] = '0' 4 else: 5 df_users.loc[df_users['zip'] == zipcode, 'zip'] = str(zipcode[:len(zipcode) - 2]) KeyError: '0'
问题排查与解决
报错原因
- 循环遍历对象被修改导致异常:循环直接遍历
df_users['zip']列,当某个邮编被修改为'0'后,后续循环会遍历到这个'0'。此时执行zipcode[:len(zipcode)-2],因len('0')=1,计算后切片结果仍为'0',而zip_dict中无'0'这个键,触发KeyError。 - 切片写法冗余且易出错:用
zipcode[:len(zipcode)-2]取前3位依赖邮编长度为5位,若遇到长度异常的邮编会出错,直接写zipcode[:3]更稳妥。 - 逐行循环效率低下:pandas设计逻辑更适合矢量化操作,逐行循环处理DataFrame属于低效写法。
修复方案
方案1:修复循环逻辑
先保存原始邮编列表,避免遍历过程中被修改后的数据干扰,同时优化切片和键查询逻辑:
# 保存原始邮编列表,避免遍历修改后的列 original_zips = df_users['zip'].tolist() for idx, zipcode in enumerate(original_zips): # 直接取前3位作为查询键 zip_prefix = zipcode[:3] # 用get方法避免键不存在的情况,默认返回0(视为人口≤20000) if zip_dict.get(zip_prefix, 0) <= 20000: df_users.loc[idx, 'zip'] = '0' else: df_users.loc[idx, 'zip'] = zip_prefix
方案2:使用pandas矢量化操作(推荐)
用apply函数实现批量处理,代码更简洁,效率远高于逐行循环:
def process_zip(zipcode): zip_prefix = zipcode[:3] # 处理键不存在的边界情况 population = zip_dict.get(zip_prefix, 0) return '0' if population <= 20000 else zip_prefix # 批量处理邮编列 df_users['zip'] = df_users['zip'].apply(process_zip)
内容的提问来源于stack exchange,提问作者Avanoc
相关产品推荐
相关产品推荐

