pandas DataFrame按占比替换低频值触发索引错误如何解决
问题描述
查阅同类参考问题后找到基础方案,按自身需求调整判断条件后编写第一版代码如下:
def clean_variables(data): for column in cat_others: data.loc[(data[column].value_counts()/data[column].count())*100 < 0.01, cat_others] = "Rare" return data X_train = clean_variables(X_train)
运行代码时出现如下索引错误:
(Missing False Grvl False Pave False Name: Alley, dtype: bool, ['Alley', 'RoofStyle', 'LandContour', 'HouseStyle', 'BldgType'])
尝试将.loc方法替换为.iloc方法后问题依然存在。报错输出中展示的列名列表就是cat_others存储的所有分类列名,替换操作本应仅在这些列上执行,初步判断是循环判断条件存在逻辑问题。
后续另外尝试编写了第二版实现代码:
def rare_replacement(data): for col in cat_others: v_counts = data[col].value_counts() rare_vals = v_counts[(v_counts/v_counts.sum()) < 0.01] rare_vals_list = list(rare_vals.index) for i,v in enumerate(data[col]): if v in rare_vals_list: data.loc[i,col] = 'Rare' return data X_train = rare_replacement(X_train)
该版本代码运行后依然无法得到预期的替换结果,需要可行解决方案。
问题根因
两版代码运行异常都是缩进错误+索引逻辑错误共同导致的:
- 第一版代码问题
value_counts()返回的布尔序列索引是列的具体取值(比如Alley列的Missing/Grvl/Pave),不是原DataFrame的行号,直接传给.loc做行筛选会出现索引长度、索引值不匹配的问题,直接触发索引报错return data被错误缩进在for循环内部,只会处理cat_others里的第一个列就直接返回结果- 赋值时直接选了
cat_others所有列做写入,哪怕判断条件正确,也会把所有列的对应行都改成Rare,不符合单列表判断的需求
- 第二版代码问题
- 逐行替换的for循环被错误放在遍历列的for循环外部,循环结束后
col只会保留cat_others里最后一个列的名称,前面所有列都不会被处理 - 同样
return data缩进错误,处理完最后一列的第一行就会终止函数返回,根本跑不完所有行的判断 - 逐行遍历的写法效率极低,数据量稍大时运行速度会非常慢
- 逐行替换的for循环被错误放在遍历列的for循环外部,循环结束后
可直接运行的修正方案
用pandas原生向量化操作实现,没有索引对齐问题,运行效率远高于逐行循环:
def clean_rare_categories(data, threshold=0.01, fill_tag="Rare"): # 如需避免修改原始数据,可放开下一行注释 # data = data.copy() for col in cat_others: # normalize=True直接返回取值占比,无需手动计算总数 val_ratio = data[col].value_counts(normalize=True) # 提取所有占比低于阈值的稀有取值 rare_vals = val_ratio[val_ratio < threshold].index.tolist() # 仅替换当前列内的稀有值 data[col] = data[col].replace(rare_vals, fill_tag) # 所有列处理完成后再返回 return data X_train = clean_rare_categories(X_train)
注意事项
- 所有循环内的逻辑要严格注意缩进对齐,返回语句必须放在遍历列的循环外部
- 不要把
value_counts()生成的取值维度的布尔序列直接用作行筛选条件,二者索引维度完全不一致 - 尽量避免用逐行遍历的方式处理pandas数据,原生的
replace、map等向量化方法运行速度会快几个数量级 - 阈值可根据业务需求自行调整,若需使用0.01%作为稀有值判断标准,把
threshold参数改为0.0001即可,无需手动做百分比乘除计算
内容的提问来源于stack exchange,提问作者Burchette
相关产品推荐
相关产品推荐

