使用Numpy创建随机数组

Python
作者

yangjh

发布日期

November 22, 2022

随机数在编程世界里有很多妙用,比如我们都玩过的消消乐游戏,消掉一块后,屏幕顶端会自动下落一部分随机色块;还有欢乐玩斗地主的时候,洗牌就是一个随机的过程。

但是有的时候我们对生成的随机数也有一定的要求,比如我们在消消乐游戏里面,各个色块出现的概率是不一样的,特别是在高难度的关卡里,程序似乎可以故意提高“游戏难度”。其实这里的随机数都是经过缜密计算、精心设计的,那下面我们就来看看,如何生成一些“高阶”的随机数。

创建[0, 1)之间的均匀分布的随机数组

# 函数的输入为若干个整数,表示输出随机数的大小为d0×d1× ...×dn
# 如果没有参数输入,则返回一个float型的随机数
numpy.random.rand(d0, d1, ..., dn)

# 产生一个大小为3×2,符合0-1之间的均匀分布的数组
arr_rand0 = np.random.rand(3, 2)
arr_rand0
Out: 
    array([[0.07870998, 0.09327187],
           [0.49848953, 0.07535019],
           [0.64401283, 0.11176563]])

创建[low, high)之间的均匀分布的随机数组

# uniform方法可以指定产生随机数的范围[low, high),size为数组的形状,输入格式为整形(一维)或者整形元祖
# 如果不指定size的话,则返回一个服从该分布的随机数
numpy.random.uniform(low=0.0, high=1.0, size=None)

# 产生一个大小为3×2,符合0-10之间的均匀分布的数组
arr_rand1 = np.random.uniform(1, 10, (3, 2))
arr_rand1
Out: 
    array([[6.72617294, 5.32504844],
           [7.6895909 , 6.97631457],
           [1.3057397 , 3.51288886]])

创建服从标准正态分布的数组(均值为0,方差为1)

# 该方法和rand类似,函数的输入为若干个整数,表示输出随机数的大小为d0×d1× ...×dn
# 如果没有参数输入,则返回一个服从标准正态分布的float型随机数
numpy.random.randn(d0, d1, ..., dn)

# 产生一个大小为3×2,符合标准正态分布的数组
arr_rand2 = np.random.randn(3, 2)
arr_rand2
Out: 
    array([[-0.70354968, -0.85339511],
           [ 0.22804958,  0.28517509],
           [ 0.736904  , -2.98846222]])

创建服从μ=loc,σ=scale的正态分布的数组

# loc:指定均值 μ; scale:指定标准差 σ
# size:输入格式为整形(一维)或者整形元祖,指定了数组的形状
numpy.random.normal(loc=0.0, scale=1.0, size=None)

# 产生一个大小为3×2,符合均值为5,标准差为10的正态分布的数组
arr_rand3 = np.random.normal(5, 10, (3, 2))
arr_rand3
Out:
    array([[ -7.77480714,  -2.68529581],
           [  4.40425363,  -8.39891281],
           [-13.08126657,  -9.74238828]])

在指定区间[low, high)中离散均匀抽样的数组

# 函数返回区间[low, high)内的离散均匀抽样,dtype指定返回抽样数组的数据类型,默认为整形
# size:输入格式为整形(一维)或者整形元祖,指定了数组的形状
numpy.random.randint(low, high=None, size=None, dtype=np.int64)

# 在[1, 5)之间离散均匀抽样,数组形状为3行2列
arr_rand4 = np.random.randint(1, 5, (3, 2))
arr_rand4
Out:
    array([[4, 4],
           [3, 3],
           [4, 2]])

对于np.random.randint(1, 5, (3, 2))的执行结果,可以这样去理解:假设现有编号分别为1、2、3、4的4个小球,我们每次有放回抽样,分别抽样6次,把每次抽得的小球编号组合并调整为3×2大小的数组。

numpy.random.randint可以非常方便地实现在某一整数区间内进行有放回的抽样,那如果我希望对具体实物进行抽样,有没有更好的方法呢?我们继续看。

对具体样本进行有放回或者无放回的抽样

# 从样本a中进行抽样,a可以为数组、列表或者整数,若为整数,表示[0,a)的离散抽样;
# replace为False,表示无放回抽样;replace为True,表示有放回抽样
# size为生成样本的大小
# p为给定数组中元素出现的概率
numpy.random.choice(a, size=None, replace=True, p=None)

我们看一个案例,小明同学在罚球线投篮命中的概率为0.65,总共投10次,我们看一下计算机的模拟结果:

# 因为理想情况下,每次投篮都不影响下一次的结果,所以把这个问题归结为有放回的抽样,一共进行10次
# shoot_lst用来存储投篮的结果
# 从["命中", "未命中"]中有放回抽样,其中命中的概率为0.65,共抽取10次,返回的格式为为numpy.ndarray
shoot_lst = np.random.choice(["命中", "未命中"], size=10, replace=True, p=[0.65, 0.35])
shoot_lst

Out: ['未命中', '命中', '未命中', '命中', '命中', '命中', '命中', '命中', '命中', '未命中']

参考文献

  1. 随机抽样 (numpy.random) | NumPy 中文
回到顶部