如何为Pandas数据集新增按团队重置的GameNumber递增列
问题场景
现有按时间顺序排列的球队比赛结果DataFrame:
| Team | Result |
|---|---|
| TeamA | Win |
| TeamA | Loss |
| TeamA | Win |
| TeamB | Loss |
| TeamB | Loss |
| TeamC | Loss |
| TeamC | Win |
| TeamC | Win |
| TeamC | Loss |
| TeamC | Loss |
需要新增GameNumber列,实现:同一球队内按比赛顺序从1开始递增计数,切换到新球队时重置为1,最终得到如下结果:
| Team | Result | GameNumber |
|---|---|---|
| TeamA | Win | 1 |
| TeamA | Loss | 2 |
| TeamA | Win | 3 |
| TeamB | Loss | 1 |
| TeamB | Loss | 2 |
| TeamC | Loss | 1 |
| TeamC | Win | 2 |
| TeamC | Win | 3 |
| TeamC | Loss | 4 |
| TeamC | Loss | 5 |
解决方案
方法一:groupby + cumcount(最简洁高效)
利用Pandas的分组计数函数cumcount(),直接为每组内的行生成连续序号,加1后得到从1开始的场次编号:
import pandas as pd # 构造原始数据(已有DataFrame可跳过此步) data = { 'Team': ['TeamA', 'TeamA', 'TeamA', 'TeamB', 'TeamB', 'TeamC', 'TeamC', 'TeamC', 'TeamC', 'TeamC'], 'Result': ['Win', 'Loss', 'Win', 'Loss', 'Loss', 'Loss', 'Win', 'Win', 'Loss', 'Loss'] } df = pd.DataFrame(data) # 生成GameNumber列 df['GameNumber'] = df.groupby('Team').cumcount() + 1
执行后即可得到目标结果。cumcount()会为每个分组内的行分配从0开始的连续整数,加1后正好匹配从1开始的场次需求。
方法二:通过shift判断分组变化再累加(适合理解底层逻辑)
如果需要手动实现分组重置的逻辑,可以通过对比当前行与上一行的球队是否相同,生成分组标记后再计数:
# 生成分组标记:球队变化时标记为1,否则为0 group_flag = (df['Team'] != df['Team'].shift()).astype(int) # 得到每个分组的全局编号 df['temp_group'] = group_flag.cumsum() # 对每个球队+临时分组的组合计数 df['GameNumber'] = df.groupby(['Team', 'temp_group']).cumcount() + 1 # 移除临时列 df.drop('temp_group', axis=1, inplace=True)
这种方法逻辑更直观,但相比第一种方法冗余,推荐优先使用第一种。
说明
explode函数用于展开DataFrame中的列表型单元格,与分组计数需求无关,因此无法解决问题。- 如果之前使用
groupby未成功,大概率是未搭配cumcount()函数,而是误用了聚合类函数(如sum/mean),这类函数无法生成每组内的连续序号。
内容的提问来源于stack exchange,提问作者Philby_Walsh
相关产品推荐
相关产品推荐

