科学计算基础软件包NumPy入门讲座:随机抽样子模块
Posted 天元浪子
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了科学计算基础软件包NumPy入门讲座:随机抽样子模块相关的知识,希望对你有一定的参考价值。
文章目录
在科研活动和日常工作中,经常会用到随机数,特别是仿真、人工智能等领域更离不开随机数。计算机系统生成的随机数都是伪随机数,NumPy 自然也不例外,但它的 random 随机抽样子模块提供了很多便捷的函数,可以满足绝大多数的应用需求。
1. 随机数
np.random.random() 是最常用的随机数生成函数,该函数生成的随机数均匀分布于[0, 1) 区间(左闭右开)。默认np.random.random() 函数返回一个浮点型随机数,该函数还可以接受一个整型或元组参数,用于指定返回的浮点型随机数数组的结构(shape)。也有很多人习惯使用 np.random.rand() 函数生成随机数,其功能和 np.random.random() 函数一样,只是 np.random.rand() 函数不接受元组参数,必须要写成多个整型参数。
>>> import numpy as np
>>> print(np.random.random())
0.29306990716963177
>>> print(np.random.random(2))
[0.894 0.88 ]
>>> print(np.random.random((2,3)))
[[0.614 0.953 0.773]
[0.383 0.909 0.988]]
np.random.randint() 是另一个常用的随机数生成函数,该函数生成的随机整数均匀分布于[low, high) 区间(左闭右开)。如果省略 low 参数,则默认 low 的值等于 0。np.random.randint()函数还有一个默认参数 size,用于指定返回的整型随机数数组的结构(shape),其代码如下。
>>> print(np.random.randint(10))
6
>>> print(np.random.randint(10, size=5))
[1 0 3 2 8]
>>> print(np.random.randint(10, size=(2,5)))
[[0 4 0 7 3]
[9 6 9 1 9]]
>>> print(np.random.randint(10, 100, size=(2,5)))
[[92 99 74 50 21]
[87 80 66 74 11]]
2. 随机抽样
随机抽样是从指定的有序列表中随机抽取指定数量的元素。随机抽样的应用比较广泛,如产品抽检、抽签排序等。NumPy 的随机抽样函数是 np.random.choice(),其原型如下。
np.random.choice(a, size=None, replace=True, p=None)
参数 a 表示待抽样的全体样本,它只接受整数或一维的数组(列表)。参数 a 如果是整数,相当于将数组 np.arange(a) 作为全体样本。参数 size 用于指定返回抽样结果数组的结构(shape)。参数 replace 用于指定是否允许多次抽取同一个样本,默认为允许。参数 p 是和全体样本集合等长的权重数组,用于指定对应样本被抽中的概率。
>>> print(np.random.choice(1,5)) # 抽签样本只有1个元素0,抽取5次
[0 0 0 0 0]
>>> print(np.random.choice(['a','b','c'], size=(3,5), p=[0.5,0.25,0.25])) # 指定权重
[['b' 'c' 'c' 'b' 'c']
['b' 'c' 'a' 'c' 'a']
['b' 'b' 'a' 'b' 'a']]
>>> print(np.random.choice(np.arange(100), size=(2,5), replace=False)) # 不允许重复
[[21 66 85 49 14]
[16 29 46 99 84]]
3. 正态分布
使用 np.random.randn() 函数是最简单的生成标准正态分布随机数的方法。np.random.randn() 函数用于生成均值为 0、标准差为 1 的正态分布(标准正态分布)随机数。该函数可以接受一个或两个整型参数,用来指定返回的符合标准正态分布的随机数数组的结构(shape)。
>>> print(np.random.randn()) # 标准正态分布,均值为0,标准差为1
1.7581590925779629
>>> print(np.random.randn(5))
[ 1.735 -1.502 -0.417 -1.22 0.653]
>>> print(np.random.randn(2,5))
[[ 0.008 1.556 -1.151 0.604 0.113]
[-1.219 1.11 -1.264 0.638 -1.388]]
如果需要生成非标准正态分布随机数,则应该使用 np.random.normal() 函数。np.random.normal() 函数默认生成均值为 0、标准差为 1 的正态分布随机数。参数 loc 用于指定均值,参数scale 用于指定标准差,参数 size 用于指定返回的符合正态分布的随机数数组的结构(shape)。从下面的代码运行结果可以看出,和使用默认标准差相比,指定标准差为 0.2 时,数据分布更加靠近均值。
>>> print(np.random.normal()) # 默认均值为0,标准差为1
-0.06260301454820448
>>> print(np.random.normal(loc=2, size=5)) # 参数loc指定均值为2
[2.112 1.881 0.798 2.533 3.235]
>>> print(np.random.normal(loc=2, scale=0.2, size=(2,5))) # 参数loc指定均值为2,参数scale指定标准差为0.2
[[2.268 2.18 1.832 1.98 1.931]
[1.585 2.304 1.914 2.054 1.637]]
4. 伪随机数的深度思考
计算机程序或编程语言中的随机数都是伪随机数。因为计算机硬件是确定的,代码是固定的,算法是准确的,通过这些确定的、固定的、准确的东西不会产生真正的随机数,除非引入这个封闭系统以外的因素。计算机系统的随机数算法一般使用线性同余或平方取中的算法,通过一个种子(通常用时钟代替)产生。这意味着,如果知道了种子和已经产生的随机数,就可能获得接下来随机数序列的信息,这就是伪随机数的可预测性。
NumPy 随机数函数内部使用了一个伪随机数生成器,这个生成器每次实例化时都需要一个种子(整数)完成初始化。如果两次初始化的种子相同,则每次初始化后生成的随机数序列就完全一致。np.random.seed() 函数可以指定伪随机数生成器的初始化种子,其代码如下。
>>> np.random.seed(12345) # 使用'12345'随机种子初始化伪随机数生成器
>>> print(np.random.random(5))
[0.93 0.316 0.184 0.205 0.568]
>>> print(np.random.random((2,3)))
[[0.596 0.965 0.653]
[0.749 0.654 0.748]]
>>> np.random.seed(12345) # 再次使用'12345'随机种子初始化伪随机数生成器
>>> print(np.random.random(5)) # 和上面完全一致
[0.93 0.316 0.184 0.205 0.568]
>>> print(np.random.random((2,3))) # 和上面完全一致
[[0.596 0.965 0.653]
[0.749 0.654 0.748]]
从上述代码中可以看出,只要指定相同的种子,接下来的随机序列就完全一致。这意味着,只有从外部引入真正的随机因子(如天空云朵的形状、邻居家无线网络信号的强度等)作为种子,才可以得到真正的随机数。
此外,NumPy 还提供了随机数生成器,可以直接操作这个生成器来生成随机数,其代码如下。
>>> r = np.random.RandomState(12345) # 使用随机数生成器也同样
>>> print(r.random(5)) # 和上面完全一致
[0.93 0.316 0.184 0.205 0.568]
>>> print(r.random((2,3))) # 和上面完全一致
[[0.596 0.965 0.653]
[0.749 0.654 0.748]]
以上是关于科学计算基础软件包NumPy入门讲座:随机抽样子模块的主要内容,如果未能解决你的问题,请参考以下文章