Pandas实现抽卡概率模拟结果异常的问题排查
Pandas模拟代码的核心bug定位
对比正确的循环逻辑,你的Pandas版本存在3个直接导致结果严重偏差的问题:
- 闭区间切片重叠,触发布尔值二次比较,逻辑完全错乱
Pandas的.loc是左闭右闭的区间切片,你写的df.loc[:100, :]实际覆盖索引0到100的101行,df.loc[100:, :]又从索引100开始覆盖到最后一行,两个切片在索引100的位置完全重叠。
执行第一步赋值后,索引0到100的所有随机浮点数已经被替换成了布尔值;执行第二步赋值时,索引100的位置已经没有原始随机浮点数了,Python会自动把布尔值按数值规则比较:True等价于1,False等价于0。这就导致索引100位置的判断完全失真:原本99.5%概率为True(没中)的位置,经过<=0.99的比较后,99.5%会变成False(代表中了)。因为这个位置每一列有99.5%的概率触发“中了”的判断,最终统计出来的抽中率自然接近100%。 - 区间划分和理论模型不匹配
你的理论没中概率是0.995^100 * 0.99^99,对应需要100次0.5%概率的抽取、99次1%概率的抽取,总计199次。按你原来的切片,重叠部分的计算逻辑已经完全失效,和原始概率模型没有任何对应关系。 - 统计方向容易搞反
你定义“False代表抽中、True代表没中”,而df.all(axis=0)(默认参数)会对每一列判断:如果列内所有值都是True(199抽全没中),返回True;只要有一个False(抽中),返回False。最终的抽中率应该是「返回False的列数 / 总模拟数」,不要直接把Counter的统计结果搞反方向。
修正后的参考实现
num_simulations = 1000 # 199行对应1-199抽,1000列对应模拟次数 df = pd.DataFrame(np.random.rand(199, num_simulations)) # 无重叠切片划分区间:前100行(索引0-99)对应0.5%概率阶段 df.loc[:99, :] = df.loc[:99, :] <= 0.995 # 后99行(索引100-198)对应1%概率阶段 df.loc[100:, :] = df.loc[100:, :] <= 0.99 # 计算每一列是否199抽全没中 all_miss = df.all() # 抽中率 = 1 - 全没中的比例 success_rate = 1 - all_miss.mean()
内容的提问来源于stack exchange,提问作者Dan Tang
相关产品推荐
相关产品推荐

