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

如何在Pandas中按目标列分组替换分类列的低频次标签

实现思路

  1. 先按目标分组列(这里是att_cat)对数据集分组
  2. 针对每个分组,单独统计指定分类列的标签出现频率,保留排名前n的高频标签
  3. 该分组下其余低频标签统一替换为{分组取值}_{分类列名}格式的通用标签
  4. 支持为不同分组设置不同的n值,适配不同分组的阈值需求

完整实现代码

import pandas as pd
import numpy as np

def rare_labels(df, target_col, cat_col, n):
    """
    参数说明:
    df: 待处理的DataFrame
    target_col: 分组依据的目标列名,示例中为'att_cat'
    cat_col: 要处理的分类列名,示例中为'proto'/'state'
    n: 保留的高频标签数量,传入int则所有分组共用n;传入dict则key为分组取值,value为对应分组的n
    """
    df = df.copy()
    
    def replace_rare(group):
        group_val = group.name
        current_n = n[group_val] if isinstance(n, dict) else n
        # 统计当前分组下分类列的频率,取前n个标签
        top_labels = group[cat_col].value_counts().index[:current_n].tolist()
        # 非top标签替换为指定格式
        group[cat_col] = np.where(group[cat_col].isin(top_labels), 
                                  group[cat_col], 
                                  f"{group_val}_{cat_col}")
        return group
    
    df = df.groupby(target_col, group_keys=False).apply(replace_rare)
    return df

使用示例

1. 构造测试数据

data = [
    [1, 0.121460, 'tcp', 'FIN', 'Normal'],
    [2, 0.649902, 'tcp', 'FIN', 'Normal'],
    [3, 1.623047, 'tcp', 'FIN', 'Normal'],
    [4, 1.681641, 'tcp', 'FIN', 'Normal'],
    [5, 0.449463, 'tcp', 'CON', 'Normal'],
    [6, 0.000009, 'udp', 'INT', 'Generic'],
    [7, 0.505859, 'udp', 'CON', 'Normal'],
    [8, 0.000009, 'udp', 'INT', 'Generic'],
    [9, 0.000009, 'udp', 'INT', 'Generic'],
    [10, 0.000009, 'tcp', 'INT', 'Generic'],
    [11, 0.222761, 'unas', 'ECO', 'Normal'],
    [12, 1.461278, 'tcp', 'CON', 'Normal'],
    [13, 1.065289, 'arp', 'FIN', 'Normal'],
    [14, 2.782646, 'udp', 'CON', 'Normal'],
    [15, 1.457923, 'tcp', 'FIN', 'Normal'],
    [16, 0.000009, 'udp', 'INT', 'Generic'],
    [18, 0.125550, 'arp', 'INT', 'Generic'],
    [19, 0.000009, 'tcp', 'INT', 'Generic'],
    [20, 0.000009, 'tcp', 'CON', 'Generic']
]
df = pd.DataFrame(data, columns=['id', 'dur', 'proto', 'state', 'att_cat'])

2. 按需求处理不同列

# 处理proto列,所有分组n=2
df = rare_labels(df, target_col='att_cat', cat_col='proto', n=2)
# 处理state列,Normal分组n=2,Generic分组n=1
df = rare_labels(df, target_col='att_cat', cat_col='state', n={'Normal':2, 'Generic':1})

运行后得到的结果和预期输出完全一致。


内容的提问来源于stack exchange,提问作者Ernesto Lopez Fune

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.08 17:27:03