Python中生成随机数
今天在一个公众号上看到了一篇有关Python基础的文章,其中提到了Numpy模块中有关生成随机数的使用;这才联想到,自己对这一块也不熟悉,每次想要验证某个函数的功能时,总是有些机械的去手动输入一些数据,显得有些low。因此,总结这篇文章供自己学习,如果也有帮到你,那也是很好的。
在此声明,本文中部分观点或内容来源于其他博文,会在文末给出相应的引用链接,文中不再具体说明来源何处。
本文主要介绍:
- random模块
- numpy.random的使用
# 版本信息
Python 3.6.8
Numpy 1.14.5
开始写的时候才发现,其中又涉及到Python中自带的random模块,查看源码后发现,这TM工程量很庞大啊;然而本着学习的态度,就是干!!!
写到后面发现,这仅仅是本人学习过程中作的笔记,并不一定能够给人很好的阅读感受;如果你也想学习Python中有关随机数的生成,强烈推荐去阅读源码以及文档;
random:
源码:import random
Numpy.random:
源码:from numpy import random
1. random模块
1.1 设置随机种子
下面介绍如何设置随机种子、获取当前随机数环境状态、设置当前随机数环境状态;
1.1.1 设置随机种子
import random
random.seed(5) # 设置随机数,用于保证每次随机生成得到的数据是一致的
1.1.2 获取当前随机数环境状态
import random
state = random.getstate() # 获取当前随机数环境状态
1.1.3 设置当前随机数环境状态
import random
state = random.getstate() # 获取当前随机数环境状态,用于下次使用
random.setstate(state) # 设置当前随机数环境状态
示例:
import random
def example_1():
num1 = random.random() # 得到一个随机数
num2 = random.random() # 得到一个随机数
print("example_1: ", num1)
print("example_1: ", num2)
# 可以发现,每次执行该部分代码,num1, num2这两个随机数总是和之前生成的不一样
def example_2():
random.seed(5) # 设置随机种子,可以得到相同的随机数序列
num3 = random.random()
num4 = random.random()
print("example_2: ", num3)
print("example_2: ", num4) # num3与num4这两个随机数不相同;但是执行多次后可以发现,这个值总是固定不变的,这就能够理解random.seed()的作用了。
state = random.getstate() # 获取当前随机数的状态,并返回;也就是说当前随机数位于num4
return state
def example_3(state):
num5 = random.random() # 由于example_2中已经设置随机种子;此时会按照随机数序列继续返回随机数
print("example_3: ", num5) # 新的随机数
random.setstate(state) # 设置随机数环境状态
num6 = random.random() # 会发现num2=num3,这是因为将随机数环境状态重置到“未生成随机数num5”前的状态。
print("example_3: ", num6)
num7 = random.random()
print("example_3: ", num7) # 会得到新的随机数
if __name__ == "__main__":
example_1()
state = example_2()
example_3(state)
example_1: 0.3469160199002712
example_1: 0.9869904001422904
example_2: 0.6229016948897019
example_2: 0.7417869892607294
example_3: 0.7951935655656966
example_3: 0.7951935655656966
example_3: 0.9424502837770503
1.2 random模块中的方法
# 这是有关Python中自带的random模块功能简介
#
"""Random variable generators.
integers
--------
uniform within range
sequences
---------
pick random element
pick random sample
pick weighted random sample
generate random permutation
distributions on the real line:
------------------------------
uniform
triangular
normal (Gaussian)
lognormal
negative exponential
gamma
beta
pareto
Weibull
distributions on the circle (angles 0 to 2pi)
---------------------------------------------
circular uniform
von Mises
```
1.3 使用:生成整形随机数
下面将介绍两个方法:randrange()、randint()
random.randrange(start, stop, step)
返回指定范围[start, stop)
内,按照指定步长step
递增的一个随机数;
示例:
import random
random.seed(5) # 保证你和我执行的结果是一致的
number = random.randrange(0, 100, 2)
print(number)
78
random.randint(a, b)
返回指定范围[a, b]
内的一个随机整数;
random.randint(self, a, b):
return self.randrange(a, b+1)
# 其实调用的还是random.randrange()方法,默认步长为1
示例:
import random
random.seed(5)
number = random.randint(0, 10)
print(number)
79
1.3 使用:生成序列随机数
都是给定序列,从序列中随机选取;
下面将介绍四种方法:choice()、shuffle()、sample()、choices()
random.choice(self, seq)
从给定序列seq
中返回一个随机值,seq
可以是列表、元组、字符串;
示例:
import random
random.seed(5)
result1 = random.choice([1, 2, 3.2, 5, 9])
result2 = random.choice('A String')
print(result1)
print(result2)
9
r
random.shuffle(self, x, random=None)
对x
进行乱序;
示例:
import random
random.seed(5)
a = [1, 2, 3, 5, 9]
random.shuffle(a)
print(a)
[1, 2, 5, 3, 9]
random.sample(self, population, k)
从序列population
中随机取出k
个数;population
的类型可以是列表、元组、集合、字符串;
注意:不放回随机抽样,k
要小于population
的长度;
示例:
import random
random.seed(5)
a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
b = (0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
c = "Hi random"
d = set([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
print(random.sample(a, 6))
print(random.sample(b, 6))
print(random.sample(c, 6))
print(random.sample(d, 6))
[9, 4, 5, 6, 7, 8]
[0, 7, 3, 5, 9, 1]
['i', 'n', 'r', 'm', 'd', 'H']
[9, 3, 0, 5, 1, 8]
random.choices(self, population, weights=None, *, cum_weights=None, k=1):
从population
中有放回的随机取k
个数据;population
的类型可以是列表、元组、字符串;
weights
表示population
中各元素的相对权重;
cum_weights
表示从前往后元素的累计权重;
注意:不限制k
的大小;
示例1:population
的类型可以是列表、元组、字符串
random.seed(5)
a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
b = (0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
c = "Hi random"
print(random.choices(a, k=3))
print(random.choices(b, k=3))
print(random.choices(c, k=3))
[6, 7, 7]
[9, 7, 9]
['H', 'a', 'm']
示例2:相对权重weights
的使用
如果指定了权重序列,则会根据权重序列进行选择;如果给定相对权重序列,则最终会转化成累计权重序列;
也就是说对应元素权重越大,越有可能被选中;
import random
random.seed(5)
a = "random"
weights = [5, 1, 15, 2, 3, 2]
b = random.choices(a, weights=weights, k=1)
print(b)
['n']
1.4 使用:生成随机实值分布
random.random() # 返回一个[0, 1)范围内的浮点数
1.4.1 均匀分布
random.uniform(self, a, b):
返回给定范围[a, b]或[a, b)
内的一个浮点数;
计算方式:
a + (b-a) * self.random()
示例:
import random
random.seed(5)
number = random.uniform(2, 10)
print(number)
6.983213559117615
1.4.2 三角分布
random.triangular(self, low=0.0, high=1.0, mode=None):
返回给定范围[low, high]
内的随机浮点数;mode
默认为边界的中点,给出对称分布;
不举示例了,因为只是出来一个在指定范围内的随机数;但是想要弄明白这个随机数是怎么计算的,需要源码;
1.4.3 正态分布
random.normalvariate(self, mu, sigma):
Args:
mu: # 表示均值
sigma: # 表示标准差
1.4.4 对数正太分布
random.lognormvariate(self, mu, sigma):
return _exp(self.normalvariate(mu, sigma)) # 使用的还是正态分布
Args:
mu: # 均值
sigma: # 标准差
1.4.5 指数分布
random.expovariate(self, lambd):
return -_log(1.0 - self.random())/lambd
该方法返回一个随机数,值的大小与lambda
有关;
假如我们想要得到1000个样本,而且这1000个样本的平均值大致为:10,则需要设定lambda=1/10=0.1
;
示例:
import random
random.seed(5)
a = []
for i in range(1000):
number = random.expovariate(0.1)
a.append(number)
print(sum(a)/len(a))
9.810064281255109 # 最后得到1000个输的平均值为10
1.4.6 von Mises 分布
random.vonmisesvariate(self, mu, kappa):
Args:
mu: # mean angle, 以弧度表示,介于(0, 2*pi)之间
kapp: # 浓度参数,大于或等于0;如果等于0,(0, 2*pi)的均匀随机角度
1.4.7 gamma分布
random.gammavariate(self, alpha, beta):
Args:
alpha: # 大于0
beta: # 大于0
# mean is alpha*beta, variance is alpha*beta**2
计算方式:
x ** (alpha - 1) * math.exp(-x / beta)
pdf(x) = --------------------------------------
math.gamma(alpha) * beta ** alpha
1.4.8 高斯分布
random.gauss(self, mu, sigma):
Args:
mu: # mean
sigma: # standard deviation
# 速度快于方法:random.normalvariate(self, mu, sigma):
1.4.9 贝塔分布
random.betavariate(self, alpha, beta):
Args:
alpha: # 大于0
beta: # 大于0
Return:
# 介于0,1之间
1.4.10 Pareto 分布
random.paretovariate(self, alpha):
u = 1.0 - self.random()
return 1.0 / u ** (1.0/alpha)
1.4.11 Weibull 分布
random.weibullvariate(self, alpha, beta):
u = 1.0 - self.random()
return alpha * (-_log(u)) ** (1.0/beta)
花了一上午的时间,终于将python自带的random模块大致搞明白了一些;然而,写到后面才发现,在平时的使用当中,根本用不了这么多,或许常用的如:random()
, randrange()
,randint()
,choice()
,shuffle()
,sample()
,后面的“分布”,可能很少用到;
random模块基本上完事了,后续不知道还会不会有再次补充、修改的机会;
接下来,继续学习Numpy模块中的random吧,希望可以顺利些;
2. numpy.random
学习的过程按照numpy.random
源码中的顺序来学习,参考文档-python3.6-numpy.random;
分成六类:
- Utility functions:实用方法
- Compatibility functions:兼容方法
- Univariate distributions:单变量分布
- Multivariate distributions:多变量分布
- Standard distributions:标准分发
- Internal functions:内部功能
========================
Random Number Generation
========================
==================== =========================================================
Utility functions
==============================================================================
random Uniformly distributed values of a given shape.
bytes Uniformly distributed random bytes.
random_integers Uniformly distributed integers in a given range.
random_sample Uniformly distributed floats in a given range.
random Alias for random_sample
ranf Alias for random_sample
sample Alias for random_sample
choice Generate a weighted random sample from a given array-like
permutation Randomly permute a sequence / generate a random sequence.
shuffle Randomly permute a sequence in place.
seed Seed the random number generator.
==================== =========================================================
==================== =========================================================
Compatibility functions
==============================================================================
rand Uniformly distributed values.
randn Normally distributed values.
ranf Uniformly distributed floating point numbers.
randint Uniformly distributed integers in a given range.
==================== =========================================================
==================== =========================================================
Univariate distributions
==============================================================================
beta Beta distribution over ``[0, 1]``.
binomial Binomial distribution.
chisquare :math:`\\chi^2` distribution.
exponential Exponential distribution.
f F (Fisher-Snedecor) distribution.
gamma Gamma distribution.
geometric Geometric distribution.
gumbel Gumbel distribution.
hypergeometric Hypergeometric distribution.
laplace Laplace distribution.
logistic Logistic distribution.
lognormal Log-normal distribution.
logseries Logarithmic series distribution.
negative_binomial Negative binomial distribution.
noncentral_chisquare Non-central chi-square distribution.
noncentral_f Non-central F distribution.
normal Normal / Gaussian distribution.
pareto Pareto distribution.
poisson Poisson distribution.
power Power distribution.
rayleigh Rayleigh distribution.
triangular Triangular distribution.
uniform Uniform distribution.
vonmises Von Mises circular distribution.
wald Wald (inverse Gaussian) distribution.
weibull Weibull distribution.
zipf Zipf's distribution over ranked data.
==================== =========================================================
==================== =========================================================
Multivariate distributions
==============================================================================
dirichlet Multivariate generalization of Beta distribution.
multinomial Multivariate generalization of the binomial distribution.
multivariate_normal Multivariate generalization of the normal distribution.
==================== =========================================================
==================== =========================================================
Standard distributions
==============================================================================
standard_cauchy Standard Cauchy-Lorentz distribution.
standard_exponential Standard exponential distribution.
standard_gamma Standard Gamma distribution.
standard_normal Standard normal distribution.
standard_t Standard Student's t-distribution.
==================== =========================================================
==================== =========================================================
Internal functions
==============================================================================
get_state Get tuple representing internal state of generator.
set_state Set state of generator.
==================== =========================================================
2.1 Utility functions:实用方法
numpy.random.random_sample(size=None)
返回范围[0.0, 1.0)
的指定大小的随机数或随机数组;
Args:
size: int 或 tuple of ints, 可选的
Returns:
out: float 或 ndarray of floats
示例:
import numpy as np
np.random.seed(5) # 设置随机数种子
a = np.random.random_sample(size=(1,))
b = np.random.random_sample(size=(2, 2))
print(a)
print(b)
[0.22199317]
[[0.87073231 0.20671916]
[0.91861091 0.48841119]]
numpy.random.bytes(length)
返回指定长度的随机字节;
Args:
length: int, Number of random bytes.
Return:
out: str, String of length.
示例:
import numpy as np
np.random.seed(5)
a = np.random.bytes(length=10)
print(a)
b'c\x8b\xd48\xceH \x0e\xefO'
numpy.random.choice(a, size=None, replace=True, p=None)
从给定的一维数组中生成随机样本;
Args:
a: 1-D array-like or int
# 如果是1-D数组,则随机返回其中一个元素;
# 如果是int,则随机返回range(a)中的一个元素;
size: int or tuple of ints, optional
# 输出维度大小,(m,n,k)
# 如果不指定,则默认为(1,)
replace: boolean, optional
# 是否重复采样,默认重复采样
p: 1-D array-like, optional
# 与a中元素对应的概率,默认均匀分布
Return:
samples: single item or ndarray
# 生成的随机样本
示例:
import numpy as np
np.random.seed(5)
aa_milne_arr = ['pooh', 'rabbit', 'piglet', 'Christopher']
a = np.random.choice(aa_milne_arr, size=5, p=[0.5, 0.1, 0.1, 0.3])
print(a)
['pooh' 'Christopher' 'pooh' 'Christopher' 'pooh']
numpy.random.permutation(x)
对指定序列进行随机置换,返回新的序列;
Args:
x: int or array_like
# 如果x是int,则会根据range(x)返回一个随机序列;
# 如果x是1-D数组,则会返回随机置换后的序列;
# 如果x是multi-D数组,则会对行进行随机置换;
示例:
# 示例1
import numpy as np
np.random.seed(5)
seq = np.random.permutation(10)
print(seq)
[9 5 2 4 7 1 0 8 6 3]
# 示例2
import numpy as np
np.random.seed(5)
seq = np.random.permutation([1, 4, 9, 12, 15])
print(seq)
[15 1 4 9 12]
# 示例3
import numpy as np
np.random.seed(5)
arr = np.arange(9).reshape((3,3))
seq = np.random.permutation(arr)
print(seq)
[[0 1 2]
[3 4 5]
[6 7 8]]
numpy.random.shuffle(x)
对给定数组进行置换,无返回值;
Args:
x: array_like
# 需要置换的数组或列表
Return:
None
# 无返回值
示例:
# 示例1
import numpy as np
np.random.seed(5)
arr = np.arange(10)
np.random.shuffle(arr)
print(arr)
[9 5 2 4 7 1 0 8 6 3]
# 示例2
import numpy as np
np.random.seed(5)
arr = np.arange(9).reshape((3,3))
np.random.shuffle(arr)
print(arr)
[[0 1 2]
[3 4 5]
[6 7 8]]
2.2 Compatibility functions:兼容方法
numpy.random.rand(d0, d1, ..., dn)
从均匀分布中返回指定维度的随机样本
类似于numpy.random.random_sample()
,后者的输出是一个元组;
numpy.random.randn(d0, d1, ..., dn)
从标准正态分布中返回指定维度的随机样本;
类似于numpy.random.standard_normal()
,后者的输出是一个元组;
Args:
d0, d1, ..., dn: int, optional
# 返回随机数组的维度
Return:
Z: ndarrau or float
# 维度大小(d0, d1, ..., dn), 数据来自于标准正态分布
想要从\(N(\mu, \sigma^2)\)得到样本,使用:
sigma * np.random.randn(...) + mu
示例:
import numpy as np
np.random.seed(5)
num = np.random.randn()
arr = 2.5 * np.random.randn(2, 4) + 3 # 返回的数组满足N(3, 6.25)
print(num)
print(arr)
0.44122748688504143
[[2.17282462 9.07692797 2.36976968 3.2740246 ]
[6.95620279 0.72691899 1.52090836 3.46900806]]
未完待续......
博主个人网站:https://chenzhen.online