Pandas分组聚合问题:按选举年份分组后正确获取对应政党
问题描述
现有如下格式的DataFrame数据:
import pandas as pd df = pd.DataFrame({'Election Yr.':[2000,2000,2000,2000,2000,2000,2005,2005,2005,2005,2005,2005], 'Party':['A','A','B','B','C','C','A','A','B','B','C','C',], 'Votes':[50,30,40,50,30,40,50,30,40,50,30,40], 'Odd':['aa','bb','cc','dd','ee','gg','ff', 'hh', 'jj', 'kk', 'll', 'yy']})
需要实现以下需求:
- 按
Election Yr.字段分组,对Votes字段求和 - 保留每个选举年份中,对应Votes最大值的
Party字段值 - 保留每个选举年份中
Odd字段的第一个值
尝试了以下代码,但由于Party是字符串类型,'Party':'idxmax'的逻辑错误(字符串的idxmax是按字典序取最大值,和Votes无关),无法得到正确结果:
df = pd.DataFrame(df.groupby(['Election Yr.'], as_index=False).agg({'Votes':'sum', 'Party':'idxmax', 'Odd':'first'}))
解决方案
方法一:自定义聚合函数
通过lambda函数关联Votes字段,找到每个组内Votes最大值对应的Party,同时完成求和和取第一个Odd值:
result = df.groupby('Election Yr.', as_index=False).agg( Total_Votes=('Votes', 'sum'), Top_Party=('Party', lambda x: x.iloc[df.loc[x.index, 'Votes'].idxmax()]), First_Odd=('Odd', 'first') )
逻辑说明:
x.index获取当前分组的所有行索引df.loc[x.index, 'Votes']拿到该分组的所有Votes值,用idxmax()找到最大值对应的行索引x.iloc[...]根据该索引取出对应的Party值
方法二:分步处理后合并
拆分任务为三个独立步骤,最后合并结果,逻辑更清晰:
# 1. 计算每个年份的Votes总和 votes_sum = df.groupby('Election Yr.', as_index=False)['Votes'].sum().rename(columns={'Votes': 'Total_Votes'}) # 2. 找到每个年份中Votes最大的行对应的Party top_party = df.loc[df.groupby('Election Yr.')['Votes'].idxmax(), ['Election Yr.', 'Party']].rename(columns={'Party': 'Top_Party'}) # 3. 提取每个年份的第一个Odd值 first_odd = df.groupby('Election Yr.', as_index=False)['Odd'].first().rename(columns={'Odd': 'First_Odd'}) # 4. 合并所有结果 result = votes_sum.merge(top_party, on='Election Yr.').merge(first_odd, on='Election Yr.')
两种方法最终得到的结果一致,输出如下:
| Election Yr. | Total_Votes | Top_Party | First_Odd |
|---|---|---|---|
| 2000 | 240 | A | aa |
| 2005 | 240 | A | ff |
内容的提问来源于stack exchange,提问作者Humoyun Usmanaliyev
相关产品推荐
相关产品推荐

