用Pandas计算各次尝试中奖人数占比,排查占比超100%问题
问题
我有如下Pandas DataFrame,正在完成一个彩票练习,想要计算第n次尝试(第1次、第2次、第3次等)中奖的人数占比。但不知为何,计算出的总占比超过了100%,希望有人能找出问题所在。
输入数据
| person | result |
|---|---|
| a | loss |
| b | win |
| a | loss |
| c | loss |
| d | loss |
| c | loss |
| c | win |
| d | win |
预期输出
Percentage of people who won on their attempt 1: 25.00% # Person B Percentage of people who won on their attempt 2: 25.00% # Person D Percentage of people who won on their attempt 3: 25.00% # Person C
当前代码
attempts_per_person = data.groupby('person').count() max_attempts = 3 # I only care about first 3 attempts for now res = [] for i in range(max_attempts): num_wins = data.loc[data.groupby('person').cumcount() == i, 'result'].eq('win').sum() res.append((num_wins / attempts_per_person.shape[0]) * 100) for i, pct in enumerate(res): print(f"Percentage of people who won on their attempt {i+1}: {pct:.2f}%")
问题分析与解决
问题根源
你的代码没有排除已经中过奖的用户。如果某个用户在多次尝试中都中奖(比如第2次和第3次都中),会被重复计入不同尝试的统计中,最终导致各次占比的总和超过100%。而你需要的应该是「首次在第n次尝试中奖的用户占比」——每个用户只会被统计一次,对应他首次中奖的那次尝试。
修正后的代码
import pandas as pd # 构造示例数据 data = pd.DataFrame({ 'person': ['a', 'b', 'a', 'c', 'd', 'c', 'c', 'd'], 'result': ['loss', 'win', 'loss', 'loss', 'loss', 'loss', 'win', 'win'] }) # 1. 给每个用户的尝试按顺序编号(第1次尝试对应编号1) data['attempt_num'] = data.groupby('person').cumcount() + 1 # 2. 筛选出中奖记录,然后保留每个用户的首次中奖记录 first_win = data[data['result'] == 'win'].groupby('person').first() # 3. 统计各首次中奖尝试的用户数量 win_counts = first_win['attempt_num'].value_counts().sort_index() # 4. 计算占比(总用户数为去重后的人数) total_people = data['person'].nunique() max_attempts = 3 # 生成结果列表,确保覆盖前max_attempts次尝试 res = [] for i in range(1, max_attempts + 1): count = win_counts.get(i, 0) res.append((count / total_people) * 100) # 打印结果 for i, pct in enumerate(res, 1): # 可选:获取对应尝试的中奖用户 users = first_win[first_win['attempt_num'] == i].index.tolist() print(f"Percentage of people who won on their attempt {i}: {pct:.2f}% # Person {'、'.join(users)}")
代码说明
- 步骤1:用
cumcount()+1给每个用户的尝试从1开始编号,对应第1、2、3次尝试。 - 步骤2:筛选所有中奖记录,再按用户分组取第一条,得到每个用户首次中奖的尝试次数。
- 步骤3:统计各尝试次数下的首次中奖用户数,确保每个用户只被统计一次。
- 步骤4:用各次数的用户数除以总用户数得到占比,即使某尝试次数没有中奖用户,也会显示0%。
运行结果
Percentage of people who won on their attempt 1: 25.00% # Person b Percentage of people who won on their attempt 2: 25.00% # Person d Percentage of people who won on their attempt 3: 25.00% # Person c
内容的提问来源于stack exchange,提问作者konichiwa
相关产品推荐
相关产品推荐

