Pandas分组后保留众值并剔除存在平局的分组
按col1分组并保留col2无平局的众数分组
需求说明
按col1分组后,仅保留col2列中唯一出现次数最多的分组;若分组内有多个值频次相同且为最高(平局),则剔除该分组。
解决方案
方法1:自定义聚合函数+过滤NA
先定义处理单组的函数,判断该组是否存在唯一众数,存在则返回对应值,否则返回空值,最后过滤掉空值对应的分组。
- 示例数据
import pandas as pd df = pd.DataFrame({ 'col1': ['A', 'A', 'B', 'B', 'B', 'C', 'C', 'C', 'C'], 'col2': ['X', 'X', 'Y', 'Z', 'Z', 'P', 'P', 'Q', 'Q'] })
- A组:
col2中X出现2次(唯一众数) - B组:
col2中Z出现2次(唯一众数) - C组:
col2中P和Q各出现2次(平局)
- 自定义聚合函数
def get_unique_mode(series): counts = series.value_counts() max_freq = counts.max() # 筛选出频次等于最大值的所有值 top_values = counts[counts == max_freq] # 仅当唯一时返回该值,否则返回空 return top_values.index[0] if len(top_values) == 1 else pd.NA
- 分组聚合并过滤
result = df.groupby('col1')['col2'].agg(get_unique_mode).dropna()
最终result输出:
col1 A X B Z Name: col2, dtype: object
方法2:先标记分组状态再过滤原数据
先给原数据添加列标记每个分组是否存在平局,再筛选出无平局的行后分组取众数。
# 计算每个分组的最高频次 df['max_freq'] = df.groupby('col1')['col2'].transform(lambda x: x.value_counts().max()) # 计算每个分组中达到最高频次的值的数量 df['top_val_count'] = df.groupby('col1')['col2'].transform( lambda x: len(x.value_counts()[x.value_counts() == x.value_counts().max()]) ) # 筛选无平局的行,再分组取众数 filtered_result = df[df['top_val_count'] == 1].groupby('col1')['col2'].agg(lambda x: x.value_counts().index[0])
输出结果和方法1一致。
内容的提问来源于stack exchange,提问作者keenan
相关产品推荐
相关产品推荐

