You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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')
)

逻辑说明:

  1. x.index获取当前分组的所有行索引
  2. df.loc[x.index, 'Votes']拿到该分组的所有Votes值,用idxmax()找到最大值对应的行索引
  3. 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_VotesTop_PartyFirst_Odd
2000240Aaa
2005240Aff

内容的提问来源于stack exchange,提问作者Humoyun Usmanaliyev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 17:15:08