Pandas如何对分类列计算rolling窗口众数过滤异常值
pandas分类列滚动窗口计算众数、剔除零星异常值实现方案
pandas内置的rolling滚动对象默认的mean()等统计方法只支持数值列,分类列要算滚动众数,直接自定义窗口应用函数即可,不需要做数值转换。
实现步骤
- 先写一个窗口内统计众数的小函数,逻辑是统计窗口内每个类别的出现频次,返回频次最高的类别
- 调用rolling方法指定窗口大小,通过apply传入自定义众数函数即可
- 可以通过
min_periods参数调整触发计算的最小窗口数据量,避免前几行因为窗口不满返回空值
代码实现
import pandas as pd # 定义窗口众数计算函数,出现并列众数时默认返回频次最高的类别中排序第一的结果 def get_rolling_mode(window_series): return window_series.value_counts().index[0] # 计算窗口大小为10的滚动众数,min_periods=1表示从第一行开始就按当前累计数据计算 df['clean_category'] = df['category'].rolling( window=10, min_periods=1 ).apply(get_rolling_mode)
效果说明
针对你给出的包含零星S异常值的示例数据,S在任意10长度的滚动窗口内占比都极低,计算出的clean_category列对应位置会被替换为窗口内占绝大多数的A类,直接实现异常值过滤的效果。
参数调整提示
- 如果你希望前9行凑不满10个数据时保留空值,去掉
min_periods=1参数即可,默认要求窗口内满10个有效值才会输出结果 - 如果遇到多个类别频次相同的并列众数场景,可以修改
get_rolling_mode函数自定义处理逻辑,比如优先保留上一行的结果、随机选择并列类别等 - 这个方法对所有非数值类型的列(文本、分类、布尔值)都适用,不需要提前做编码转换
内容的提问来源于stack exchange,提问作者SimonDL
相关产品推荐
相关产品推荐

