斯诺克数据处理:如何获取连续击球次数而非累计求和?
解决斯诺克每局玩家最高连续击球次数统计问题
我来帮你搞定这个统计需求!你之前用shift+cumsum生成分组的思路是对的,但问题出在没有先按Game_id做局内分组——连续击球是同一局内的行为,跨局的玩家切换不能算进同一个连续段里。调整一下分组逻辑就能得到你想要的结果,具体步骤和代码如下:
实现步骤
- 生成局内连续击球分组:先按
Game_id分组,在每一局内部判断当前行的玩家是否和上一行相同,生成仅在该局内有效的连续段编号。 - 统计每个连续段的击球次数:对每个(局ID, 连续段编号, 玩家ID)组合,统计该段的击球次数(也就是该组的行数)。
- 提取每局每个玩家的最大连续次数:按(局ID, 玩家ID)分组,取每个组内的最大击球次数,就是目标结果。
完整代码示例
假设你的数据集存储在名为df的Pandas DataFrame中,列名是Game_id和Player ID:
import pandas as pd # 1. 生成每局内的连续击球分组(关键:先按Game_id做局内判断) df['subgroup'] = df.groupby('Game_id')['Player ID'].transform( lambda x: (x != x.shift(1)).cumsum() ) # 2. 统计每个连续段的击球次数 continuous_shot_counts = df.groupby(['Game_id', 'subgroup', 'Player ID']).size().reset_index(name='count') # 3. 按局和玩家提取最大连续击球次数 final_result = continuous_shot_counts.groupby(['Game_id', 'Player ID'])['count'].max().reset_index( name='Maximum Continuous Shots' ) # 输出结果,格式和你期望的一致 print(final_result)
代码解释
- 第一步的
transform方法确保我们的连续段判断严格限制在同一局内,不会把不同局的同玩家击球错误合并成一个连续段。 - 第二步的
size()会统计每个连续段的行数,也就是该玩家在这个连续回合里的击球次数(符合斯诺克规则:击球入袋可继续,直到未击中,所以连续行就是连续击球)。 - 第三步的
max()直接提取每个玩家在该局的最高连续击球记录,完美匹配你想要的输出格式。
验证示例
比如用你给出的部分数据:
| Game_id | Player ID |
|---|---|
| 5d6576aab80c990500e3ce5a | 2ff211 |
| 5d6576aab80c990500e3ce5a | 2ff250 |
| 5d6576aab80c990500e3ce5a | 2ff211 |
| 5d6576aab80c990500e3ce5a | 2ff211 |
运行代码后,该Game_id下的结果会是:
| Game_id | Player ID | Maximum Continuous Shots |
|---|---|---|
| 5d6576aab80c990500e3ce5a | 2ff211 | 2 |
| 5d6576aab80c990500e3ce5a | 2ff250 | 1 |
这和数据中的连续击球情况完全匹配,要是有更长的连续段,代码也能准确捕获最大值。
内容的提问来源于stack exchange,提问作者Abhas Mehrotra
相关产品推荐
相关产品推荐

