Pandas数据清洗解析薪资字段触发IndexError索引越界问题
问题说明
- 原始代码来源:Ken Jee
- 代码目标是从招聘数据的
Salary Estimate字段中清洗提取最低薪资、最高薪资,计算平均薪资,原始实现代码如下:
Salary = df['Salary Estimate'].apply(lambda x:x.split('(')[0]) minus_Kd = Salary.apply(lambda x:x.replace('K','').replace('$','')) min_hr=minus_Kd.apply(lambda x:x.lower().replace('per hour;','').replace('employer provided salary:','')) df['min_salary'] = min_hr.apply(lambda x: x.split('-')[0]) df['max_salary'] = min_hr.apply(lambda x: x.split('-')[1]) df['avg_salary']=(df.min_salary+df.max_salary)/2
- 运行时触发报错:
df['max_salary'] = min_hr.apply(lambda x: x.split('-')[1]) IndexError: list index out of range
- 待清洗字段部分样本数据:
- Employer Provided Salary:$78K - $191K
- $77K - $107K (Glassdoor est.)
- 核心疑问:按照Python零索引规则,字符串按
'-'执行split拆分后,索引0、1应分别对应分隔符左右两侧内容,为何会触发列表索引超出范围的错误?
错误原因
触发越界的核心原因非常直接:经过你的清洗逻辑处理后,部分条目字符串里根本不存在'-'分隔符,此时x.split('-')返回的列表长度只有1,强行取索引为1的元素必然超出列表范围。具体bug点都在清洗规则的硬编码问题上:
- 替换规则带了多余标点:你写的替换目标是
'per hour;',硬编码了末尾的分号,但实际源数据里"per hour"后大多没有分号,对应无关内容根本替换不掉 - 匹配字符串被代码换行截断:
replace('employer provided salary:','')这部分因为代码手动换行,传入replace的匹配串是断裂的,根本匹配不到完整的"employer provided salary:"前缀,你给出的第一个样本里的雇主提供薪资前缀就清理不掉 - 没有做格式校验:默认所有薪资条目都是
数值-数值的区间格式,完全没考虑存在单值薪资、分隔符缺失的异常条目
额外提一个隐藏bug:原代码split得到的薪资值是字符串格式,不转成数值类型直接做加法会变成字符串拼接,就算不触发越界,也根本算不出正确的平均薪资。
修复代码
调整清洗规则,去掉硬编码的多余标点,修正匹配字符串,增加格式校验和类型转换,参考实现如下:
import pandas as pd # 提取括号前的薪资主体内容 salary_raw = df['Salary Estimate'].apply(lambda x: x.split('(')[0]) # 移除薪资单位和货币符号 salary_clean = salary_raw.apply(lambda x: x.replace('K', '').replace('$', '')) # 统一转小写,移除无关前缀,清理首尾空格 salary_clean = salary_clean.apply( lambda x: x.lower() .replace('per hour', '') .replace('employer provided salary:', '') .strip() ) # 封装薪资解析逻辑,兼容单值、区间两种格式 def split_salary(salary_str): parts = [p.strip() for p in salary_str.split('-')] if len(parts) >= 2: return int(parts[0]), int(parts[1]) # 单值薪资默认最低、最高薪资相等,可根据业务规则调整 single_val = int(parts[0]) return single_val, single_val # 生成最低、最高薪资字段 df[['min_salary', 'max_salary']] = salary_clean.apply(lambda x: pd.Series(split_salary(x))) # 计算平均薪资 df['avg_salary'] = (df['min_salary'] + df['max_salary']) / 2
可以先打印
salary_clean的取值,确认所有无关内容都清理干净后再做拆分,避免脏数据导致解析错误。
内容的提问来源于stack exchange,提问作者BuffaloJ
相关产品推荐
相关产品推荐

