Python中生成随机数

  今天在一个公众号上看到了一篇有关Python基础的文章,其中提到了Numpy模块中有关生成随机数的使用;这才联想到,自己对这一块也不熟悉,每次想要验证某个函数的功能时,总是有些机械的去手动输入一些数据,显得有些low。因此,总结这篇文章供自己学习,如果也有帮到你,那也是很好的。

  在此声明,本文中部分观点或内容来源于其他博文,会在文末给出相应的引用链接,文中不再具体说明来源何处。

本文主要介绍:

  • random模块
  • numpy.random的使用
# 版本信息
Python 3.6.8
Numpy 1.14.5

开始写的时候才发现,其中又涉及到Python中自带的random模块,查看源码后发现,这TM工程量很庞大啊;然而本着学习的态度,就是干!!!

写到后面发现,这仅仅是本人学习过程中作的笔记,并不一定能够给人很好的阅读感受;如果你也想学习Python中有关随机数的生成,强烈推荐去阅读源码以及文档;

random:

源码:import random

文档:文档-python3.6-random

Numpy.random:

源码:from numpy import random

文档:文档-v1.14-numpy.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默认为边界的中点,给出对称分布;

维基百科-Triangular distribution

不举示例了,因为只是出来一个在指定范围内的随机数;但是想要弄明白这个随机数是怎么计算的,需要源码;

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'cx8bxd48xceH x0exefO'

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

Reference

原文地址:https://www.cnblogs.com/chenzhen0530/p/10649353.html