Pandas:如何获取每个分组下的两个最大子组求和值?
问题:DataFrame分组求和后取每组前两大值并避免双重索引
我有一个包含A、B、C列的DataFrame,需先按A分组,再按B子组计算C列的求和值,之后获取每个A分组下的两个最高求和值。
示例数据
data = {'State': ['NY', 'NY', 'NY', 'NY', 'CA', 'CA', 'CA', 'CA'], 'City': ['New York', 'Buffalo', 'New York', 'Albany', 'SF', 'LA', 'SF', 'SD'], 'Value': [25, 30, 35, 40, 10, 15, 20, 10],} df = pd.DataFrame(data)
预期结果
| State | City | Sum of Value |
|---|---|---|
| NY | NY | 60 |
| NY | Albany | 40 |
| CA | SF | 30 |
| CA | LA | 10 |
注:根据示例数据,LA的Sum of Value应为15,此处可能是笔误
尝试的代码
summed = df.groupby(['A','B'])['C'].sum() grouped = summed.groupby('A').nlargest(2)
注:此处A对应示例数据的State列,B对应City列,C对应Value列。该代码能得到正确结果,但存在A列作为双重索引的问题,有没有更简洁的方法避免双重索引?
解决方法
方法一:先重置索引再分组筛选
先将分组求和后的双重索引转为普通列,再按A列分组取每组求和值最大的2条数据:
# 按State和City求和,重置索引生成普通列 summed = df.groupby(['State', 'City'])['Value'].sum().reset_index(name='Sum of Value') # 按State分组,取每组Sum of Value前两大的记录 result = summed.groupby('State').apply(lambda x: x.nlargest(2, 'Sum of Value')).reset_index(drop=True)
方法二:在双重索引基础上直接处理
保留分组求和后的双重索引,通过移除外层索引并重置最终索引来得到普通列结构:
result = df.groupby(['State', 'City'])['Value'].sum()\ .groupby(level=0)\ .nlargest(2)\ .reset_index(level=0, drop=True)\ .reset_index(name='Sum of Value')
方法三:用排名筛选
先计算每组内的求和值排名,再筛选排名前2的记录:
summed = df.groupby(['State', 'City'])['Value'].sum().reset_index(name='Sum of Value') # 计算每个State组内的求和值排名(降序,相同值保留原始顺序) summed['rank'] = summed.groupby('State')['Sum of Value'].rank(ascending=False, method='first') # 筛选排名前2的记录并移除排名列 result = summed[summed['rank'] <= 2].drop('rank', axis=1)
以上三种方法都能得到无双重索引的结果,可根据个人习惯选择。
内容的提问来源于stack exchange,提问作者Q-Win
相关产品推荐
相关产品推荐

