在Pandas DataFrame中为每组计算指定众数并标记is_mode列
问题:为分组DataFrame标记指定众数行
需求:现有包含property、value、count三列的Pandas DataFrame,其中(property, value)组合唯一。需新增is_mode列,标记每行count是否为对应property分组的指定众数——分组存在多个众数时,取最小的众数作为判定标准。
示例输入
property,value,count p1,v1,20 p1,v2,50 p1,v3,50 p2,v4,10 p2,v5,20
期望输出
property,value,count,is_mode p1,v1,20,False p1,v2,50,True p1,v3,50,True p2,v4,10,True p2,v5,20,False
遇到的问题
尝试使用pd.Series.mode配合groupby.agg或transform时,出现大量NaN值。例如测试以下DataFrame:
property,value,count p1,v1,200 p1,v2,60 p1,v3,60
期望mode列全为60,但实际返回全NaN。
原因分析
pd.Series.mode在分组存在多个众数时,会返回一个包含所有众数的Series(多值),而transform要求每个分组返回的结果要么是标量,要么是与分组长度一致的序列。多值结果无法正确广播到原DataFrame的行,因此产生NaN。
解决方案
自定义聚合函数,确保每个分组返回单个最小众数,再通过transform映射回原DataFrame,最后对比生成is_mode列。
完整代码
import pandas as pd # 自定义函数:获取分组中最小的众数 def get_min_mode(series): modes = series.mode() return modes.min() # 构造示例DataFrame df = pd.DataFrame({ 'property': ['p1', 'p1', 'p1', 'p2', 'p2'], 'value': ['v1', 'v2', 'v3', 'v4', 'v5'], 'count': [20, 50, 50, 10, 20] }) # 添加分组的最小众数列 df['mode'] = df.groupby('property')['count'].transform(get_min_mode) # 生成is_mode标记列 df['is_mode'] = df['count'] == df['mode'] # 查看结果 print(df)
简化写法(无需保留mode列)
df['is_mode'] = df.groupby('property')['count'].transform( lambda s: s == s.mode().min() )
测试验证
针对第二个测试用例:
test_df = pd.DataFrame({ 'property': ['p1', 'p1', 'p1'], 'value': ['v1', 'v2', 'v3'], 'count': [200, 60, 60] }) test_df['is_mode'] = test_df.groupby('property')['count'].transform( lambda s: s == s.mode().min() ) print(test_df)
输出结果符合预期:
property value count is_mode 0 p1 v1 200 False 1 p1 v2 60 True 2 p1 v3 60 True
内容的提问来源于stack exchange,提问作者Mario Berg
相关产品推荐
相关产品推荐

