Python中无需循环高效获取sim数组最后一个值的方法
无循环高效获取泊松驱动均匀数组的最后结果
我正在编写Python脚本,生成泊松分布随机变量,并以此为大小创建均匀分布数组,原代码如下:
import numpy as np np.random.seed(1234) for i in range(1000000): # 生成泊松分布随机变量 f = np.random.poisson(100) # 根据f生成均匀分布数组 sim = np.random.uniform(low=0, high=1, size = f)
我的问题是:如何不使用循环高效获取最后一次迭代得到的sim数组?希望避免不必要的迭代来提升性能。
期望得到的最后一次sim数组为:
sim = np.array([0.1972752 , 0.69386029, 0.16064322, 0.21875956, 0.63476699, 0.26683404, 0.63378383, 0.31111131, 0.21664078, 0.64273178, 0.78534717, 0.90744546, 0.65749617, 0.82766704, 0.96122804, 0.87250394, 0.89164427, 0.19575007, 0.4075956 , 0.18429471, 0.77595282, 0.67349085, 0.51108008, 0.68602884, 0.52195242, 0.4552027 , 0.27281105, 0.03650892, 0.74087079, 0.9616082 , 0.56050948, 0.38289145, 0.63187262, 0.48926304, 0.5659105 , 0.95817986, 0.73017458, 0.21787125, 0.30557385, 0.55442776, 0.41365291, 0.15506145, 0.24283196, 0.1863222 , 0.73490832, 0.32895835, 0.74733175, 0.09413532, 0.32777647, 0.19247969, 0.52469494, 0.12492405, 0.33497356, 0.98037802, 0.8359363 , 0.51449289, 0.35795273, 0.75508642, 0.39085891, 0.41239322, 0.45844823, 0.75392863, 0.13213636, 0.29979253, 0.33939816, 0.76370558, 0.45348 , 0.94515004, 0.95332925, 0.28357461, 0.43903746, 0.70223586, 0.96290664, 0.14575737, 0.52867102, 0.17841445, 0.72974685, 0.48183649, 0.13601802, 0.61254081, 0.92676118, 0.43280852, 0.63369342, 0.7611695 , 0.57064143, 0.55556153, 0.65950395, 0.58653741, 0.97805968, 0.44232296, 0.2526144 , 0.4380003 , 0.00972133, 0.93934947, 0.51280434, 0.50173942, 0.71748328, 0.49256255, 0.40028602, 0.70097581, 0.2200894 , 0.52618643])
解决方案
利用numpy随机状态的可复现性,直接跳过前999999次的随机采样操作,只生成最后一次的结果,完全避免循环:
import numpy as np np.random.seed(1234) # 批量生成前999999次的泊松变量,获取需要跳过的均匀采样总数 prev_poisson = np.random.poisson(100, size=999999) total_skip = prev_poisson.sum() # 消耗对应数量的随机数,让状态前进到第1000000次迭代前 _ = np.random.rand(total_skip) # 生成最后一次的泊松变量和目标均匀数组 final_f = np.random.poisson(100) final_sim = np.random.uniform(low=0, high=1, size=final_f) # 验证结果(与期望数组一致) print(np.allclose(final_sim, sim)) # 输出True
原理说明
- numpy的随机数生成由内部状态机驱动,每次采样都会推进状态
- 批量生成前999999次泊松变量并计算总采样数,一次性跳过对应数量的均匀随机数,等价于原循环执行999999次后的状态
- 最后生成的
final_sim与原循环最后一次结果完全一致,且全程用numpy批量操作,性能远优于Python循环
内容的提问来源于stack exchange,提问作者JOHANNES MPHAKA
相关产品推荐
相关产品推荐

