如何为高基数列中频数超阈值的类别创建哑变量?
处理高基数列的高频类别哑变量生成方案
没问题,这是高基数分类特征处理里很常见的需求,我给你整理了几个实用的Pandas/Scikit-learn实现方案,你可以根据自己的场景选:
方案1:Pandas快速生成(含统一低频类别)
这个方案会先把所有频次低于995的类别统一归为「Other」,再生成哑变量,避免生成过多冗余列:
import pandas as pd # 1. 计算各类别频次,筛选出频次>995的高频类别 degree_counts = df['Education_Degree'].value_counts() high_freq_degrees = degree_counts[degree_counts > 995].index.tolist() # 2. 预处理原列:高频类别保留原值,低频替换为"Other" df['Education_Degree_processed'] = df['Education_Degree'].apply( lambda x: x if x in high_freq_degrees else 'Other' ) # 3. 生成哑变量并合并到原DataFrame dummies = pd.get_dummies(df['Education_Degree_processed'], prefix='Degree') df = pd.concat([df, dummies], axis=1)
方案2:仅为高频类别生成哑变量(不统一低频)
如果你不想为低频类别生成「Other」列,只想给每个高频类别单独创建哑变量,低频类别对应所有哑变量列都为0,可以用这个更直接的方式:
import pandas as pd # 步骤1同上,先筛选高频类别 degree_counts = df['Education_Degree'].value_counts() high_freq_degrees = degree_counts[degree_counts > 995].index.tolist() # 逐个为高频类别创建哑变量列(把空格换成下划线避免列名异常) for degree in high_freq_degrees: clean_degree_name = degree.replace(" ", "_") df[f'Degree_{clean_degree_name}'] = (df['Education_Degree'] == degree).astype(int)
方案3:Scikit-learn实现(适配机器学习流水线)
如果你的后续流程需要接入机器学习流水线,用OneHotEncoder会更规范:
import pandas as pd import numpy as np from sklearn.preprocessing import OneHotEncoder # 步骤1同上,筛选高频类别 degree_counts = df['Education_Degree'].value_counts() high_freq_degrees = degree_counts[degree_counts > 995].index.tolist() # 预处理:低频类别转为"Other" df['Education_Degree_processed'] = np.where( df['Education_Degree'].isin(high_freq_degrees), df['Education_Degree'], 'Other' ) # 初始化编码器并生成哑变量 encoder = OneHotEncoder(categories=[high_freq_degrees + ['Other']], sparse_output=False) dummies = encoder.fit_transform(df[['Education_Degree_processed']]) # 转为DataFrame并合并 dummies_df = pd.DataFrame(dummies, columns=encoder.get_feature_names_out(['Degree'])) df = pd.concat([df, dummies_df], axis=1)
补充说明
- 从你的value_counts结果来看,高频类别应该是:
Masters Degree in Mathematics、Bachelors Degree in Physics、Bacherlors Degree、Masters Degree in Mechanics、Masters Degree这几个(如果需要包含刚好等于995的Masters Degree in Economics,把条件改成>=995就行) - 如果不需要保留预处理后的
Education_Degree_processed列,生成哑变量后可以用df.drop('Education_Degree_processed', axis=1)删掉
内容的提问来源于stack exchange,提问作者Dimi
相关产品推荐
相关产品推荐

