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

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缩进错误,处理完最后一列的第一行就会终止函数返回,根本跑不完所有行的判断
    • 逐行遍历的写法效率极低,数据量稍大时运行速度会非常慢
可直接运行的修正方案

用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.01 04:12:31