Pandas按分组内列求和结果排名出错,求修正方法
问题分析与解决方案
你的代码问题出在分组求和的维度错误:原代码仅按UNIT分组后对SOLD_NO求和,得到的是整个部门的总销量(同一个部门内所有行的求和结果都相同),后续的rank是对全表的这个值进行排名,自然会出现多个部门共享同一排名、甚至只有总销量最高的部门才有排名1的情况,完全不符合“按部门内员工的个人总销量排名”的需求。
正确的实现步骤
需要先按UNIT+STAFF_ID分组计算每个员工的总销量,再按UNIT分组对员工总销量进行排名,最后将排名映射回原DataFrame。以下提供两种简洁的实现方式:
方式一:分步汇总后合并
# 1. 计算每个员工在所属部门的总销量 staff_sold_total = df.groupby(['UNIT', 'STAFF_ID'])['SOLD_NO'].sum().reset_index(name='TOTAL_SOLD') # 2. 按部门对员工总销量做降序密集排名 staff_sold_total['RANKING'] = staff_sold_total.groupby('UNIT')['TOTAL_SOLD'].rank(ascending=False, method='dense') # 3. 将排名合并回原DataFrame df = df.merge(staff_sold_total[['UNIT', 'STAFF_ID', 'RANKING']], on=['UNIT', 'STAFF_ID'], how='left')
方式二:用transform一步完成(无需中间表)
# 先计算每个员工在部门内的总销量(同一员工的所有行都会得到相同的总销量) df['TOTAL_SOLD'] = df.groupby(['UNIT', 'STAFF_ID'])['SOLD_NO'].transform('sum') # 再按部门对总销量做降序密集排名 df['RANKING'] = df.groupby('UNIT')['TOTAL_SOLD'].rank(ascending=False, method='dense') # 若不需要中间列TOTAL_SOLD,可直接删除 df.drop('TOTAL_SOLD', axis=1, inplace=True)
验证逻辑
两种方式都会保证:
- 每个
UNIT组内,总销量最高的员工排名为1 - 相同总销量的员工会得到相同排名(
method='dense'会让后续排名连续,无间隔) - 每个部门的排名独立计算,不会受其他部门影响
内容的提问来源于stack exchange,提问作者theluncheonmeat
相关产品推荐
相关产品推荐

