向量化比对Numpy数组与矩阵每行:Bingo中奖概率模拟问题
宾果游戏中奖校验向量化实现方案
核心实现代码
你可以直接通过numpy的广播机制实现纯向量化的逐行校验,无需任何Python层面的循环,100万样本量的计算耗时通常在1秒以内:
import numpy as np # 你已有的代码,补充replace=False符合无放回抽取规则 my_chosen_balls = np.random.choice(range(1,51), 15, replace=False) samples_30_balls = np.random.choice(range(1,51), (1_000_000, 30), replace=False) # 逐行校验:判断每行是否包含全部15个选号 # 写法1:广播直接比对,逻辑直观 hit_mask = (samples_30_balls[..., np.newaxis] == my_chosen_balls).any(axis=1).all(axis=1) # 写法2:用np.isin简化代码,性能接近 # hit_mask = np.all(np.isin(my_chosen_balls, samples_30_balls), axis=1) # 计算模拟中奖概率 win_prob = hit_mask.mean() print(f"模拟中奖概率:{win_prob:.4f}")
逻辑说明
- 给30球样本矩阵新增最后一个维度,形状从
(1000000, 30)变为(1000000, 30, 1),和形状为(15,)的选号数组广播匹配后,得到(1000000, 30, 15)的布尔比对矩阵 - 沿第二个维度(每行的30个球)做
any聚合,得到(1000000, 15)的矩阵,每个值代表对应选号是否在该行样本中出现 - 沿最后一个维度(15个选号)做
all聚合,得到(1000000,)的布尔数组,值为True即代表该行样本中奖 - 对布尔数组求均值即可得到模拟的中奖概率,结果会和理论值
C(35,15)/C(50,30) ≈ 0.0083非常接近
内容的提问来源于stack exchange,提问作者Sander van den Oord
相关产品推荐
相关产品推荐

