Python中生成隨機數

  今天在一個公衆號上看到了一篇有關Python基礎的文章,其中提到了Numpy模塊中有關生成隨機數的使用;這才聯想到,本身對這一塊也不熟悉,每次想要驗證某個函數的功能時,老是有些機械的去手動輸入一些數據,顯得有些low。所以,總結這篇文章供本身學習,若是也有幫到你,那也是很好的。python

  在此聲明,本文中部分觀點或內容來源於其餘博文,會在文末給出相應的引用連接,文中再也不具體說明來源何處。數組

本文主要介紹:app

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

開始寫的時候才發現,其中又涉及到Python中自帶的random模塊,查看源碼後發現,這TM工程量很龐大啊;然而本着學習的態度,就是幹!!!dom

寫到後面發現,這僅僅是本人學習過程當中做的筆記,並不必定可以給人很好的閱讀感覺;若是你也想學習Python中有關隨機數的生成,強烈推薦去閱讀源碼以及文檔;函數

random:學習

源碼:import randomflex

文檔:文檔-python3.6-random網站

Numpy.random:spa

源碼: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'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

Reference

相關文章
相關標籤/搜索