Pandas DataFrame分组后返回占比超n%的列最常见值,否则返回NA
Pandas分组返回占比超阈值的最常见值
实现思路
针对每个分组,先计算目标字符串列中各值的出现占比,取占比最高的值,若该值占比超过设定的百分比阈值则返回它,否则返回'NA'。
示例代码
1. 准备测试数据
import pandas as pd df = pd.DataFrame({ 'group': ['A', 'A', 'A', 'A', 'B', 'B', 'B', 'C', 'C'], 'str_col': ['x', 'x', 'y', 'x', 'a', 'b', 'b', 'm', 'n'] })
2. 通用函数实现
def get_dominant_value(df, group_col, target_col, threshold_pct): # 计算每个分组内各值的占比 group_pct = df.groupby(group_col)[target_col].value_counts(normalize=True).reset_index(name='pct') # 提取每个分组占比最高的记录 top_per_group = group_pct.groupby(group_col).nth(0) # 根据阈值判断返回值 top_per_group['dominant_value'] = top_per_group.apply( lambda row: row[target_col] if row['pct'] >= threshold_pct / 100 else 'NA', axis=1 ) # 整理结果格式 return top_per_group[['dominant_value']]
3. 调用测试(阈值设为60%)
result = get_dominant_value(df, 'group', 'str_col', 60) print(result)
输出结果:
dominant_value group A x B NA C NA
4. 更紧凑的聚合写法
如果偏好更简洁的代码,可以直接在groupby.agg中使用自定义函数:
def dominant_value(series, threshold_pct): count_pct = series.value_counts(normalize=True) if count_pct.empty: return 'NA' top_val, top_pct = count_pct.index[0], count_pct.iloc[0] return top_val if top_pct >= threshold_pct / 100 else 'NA' # 调用方式 result = df.groupby('group')['str_col'].agg(dominant_value, threshold_pct=60).reset_index(name='dominant_value')
关键细节说明
value_counts(normalize=True):自动计算每个值在分组内的占比,无需手动计算总数再求比例- 处理空分组:若分组内无数据,函数会返回
'NA',避免报错 - 阈值参数:支持任意百分比输入(如60代表60%),内部自动转换为小数进行比较
内容的提问来源于stack exchange,提问作者Yandle
相关产品推荐
相关产品推荐

