1. 程式人生 > >Python隨機數小結——random和np.random的區別與聯絡

Python隨機數小結——random和np.random的區別與聯絡

在python中,有兩個模組可以產生隨機數:
1. python自帶random包: 提供一些基本的隨機數產生函式,可滿足基本需要
2. numpy.random:提供一些產生隨機數的高階函式,滿足高階需求

本文先分別介紹這兩個包的常用函式,文末將總結一下兩個包的區別。

目錄

random 介紹

函式彙總

函式 功能 返回 備註
random.random() 生成一個 [0,1) 之間的均勻分佈浮點數 一個浮點數
random.uniform(a,b) 生成一個 [a,b] 之間的均勻分佈的浮點數,相當於 a + (b-a) * random.random() 一個浮點數 可以存在 a>b 的情況
random.randint(a, b) 生成一個 [a,b] 之間的隨機整數 一個整數
random.randrange(a, b, step) 生成一個[a,b)之間間隔步長為step的隨機整數 一個整數 如random.randrange(0, 20, 2),相當於從[0,2,4,6,…,18]中隨機取一個
random.choice(seq) 從特定序列中隨機取一個元素 一個元素 seq:字串,列表,元組,range(a, b)**等。 若seq為空,則返回IndexError
random.choices(seq, weights=None, *, cum_weights=None, k=1) (依概率)從指定序列中(有放回)隨機抽取 k 個元素,原始序列不變。可以設定 weights 或是 cum_weights 來改變元素權重 多個元素 seq:字串,列表,元組,range(a, b)等:k 必須顯式地賦值
random.sample(seq,k) 指定序列中(無放回)隨機抽取 k 個元素,原始序列不變 多個元素 seq:字串,列表,元組,range(a, b)等
random.shuffle(lst) 在原列表上將元素打亂,洗牌,原始序列改變 功能函式: 返回原序列打亂後的list lst: 只支援列表
import random

random.random()             # 0.5102632768396692
random.uniform(0,10)        # 6.890853912057401
random.randint(0,10)        # 5
random.randrange(0,10,2)    # 4


# random.choice()
string = 'nice to meet you'
tup = ('a', 'b', 'c', 'd')
lst = ['a', 'b', 'c', 'd']
random.choice(string)       # e
random.choice(tup)          # c
random.choice(lst)          # a


# random.choices()
lst = ['a', 'b', 'c', 'd']
random.choices(lst,k=3)     # ['a', 'a', 'c']


# random.sample()
string = 'nice to meet you'
tup = ('a', 'b', 'c', 'd')
lst = ['a', 'b', 'c', 'd']
random.sample(string,2)        # ['e', 'i']
random.sample(tup,2)           # ['c', 'b']
random.sample(lst,2)           # ['a', 'b']


# random.shuffle()
lst = ['a', 'b', 'c', 'd']
random.shuffle(lst)
print(lst)                     # ['b', 'd', 'c', 'a']

一下函式均輸出一個數

函式 功能
random.random() 均勻分佈: [0,1)之間
random.uniform(a, b) 均勻分佈: [a,b]之間
random.gauss(mu, sigma) 高斯分佈:以 mu 為均值,sigma 為標準差。guass()比normalvariate()稍快
random.normalvariate(mu, sigma) 正態分佈:以 mu 為均值,sigma 為標準差
random.lognormvariate(mu, sigma) 對數正態分佈
random.expovariate(lambd) 指數分佈
random.triangular(low, high, mode) 三角分佈
random.betavariate(alpha, beta) Beta分佈
random.weibullvariate(alpha, beta) 韋伯分佈
random.gammavariate(alpha, beta) Gamma分佈
random.paretovariate(alpha) Pareto 分佈

隨機種子相關

函式 功能 備註
random.seed(a=None, version=2) 初始化隨機種子 a 如果是 None 則使用當前的種子。 a 可以是 str, bytes, bytearray, 都會被轉成 int。
random.getstate() 取得隨機器內部狀態
random.setstate(state) 設定隨機器內部狀態 state需為從 random.getstate() 獲得的 state
import random
random.seed('foobar')     # 設定 random seed

# 隨意消耗一些亂數
random.randint(0, 100)    # 32
random.randint(0, 100)    # 31
random.randint(0, 100)    # 44

rs = random.getstate()    # 儲存當前的亂數狀態

r0 = [random.randint(0, 100) for _ in range(10)]  # 生成 10 個亂數
random.setstate(rs)                               # 恢復亂數狀態
r1 = [random.randint(0, 100) for _ in range(10)]  # 生成 10 個亂數

# r0, r1 隨機數應該一樣
r0 == r1                                          # True

注意:

如果要產生隨機密碼或token,請使用secrets模組,因為安全性問題,絕對不要使用random來產生密碼。

Reference

numpy.random 介紹

函式彙總

函式 功能 備註
numpy.random.seed(seed=None) 設定隨機種子 seed : int or 1-d array_like, optional
numpy.random.rand(d0,d1,…,dn) 返回給定維度的array,每個數是服從開區間[0,1)均勻分佈的浮點數
numpy.random.randn(d0,d1,…,dn) 返回給定維度的array,每個數是服從標準正態分佈的浮點數
numpy.random.random_sample(size=None) 生成[0,1)之間均勻分佈的浮點數
numpy.random.random(size=None) 生成[0,1)之間均勻分佈的浮點數
numpy.random.ranf(size=None) 生成[0,1)之間均勻分佈的浮點數
numpy.random.sample(size=None) 生成[0,1)之間均勻分佈的浮點數
numpy.random.randint(low, high=None, size=None, dtype=’l’) 返回給定維度的整數array,每個數是開區間[low,high)或[0,low)均勻分佈整數 dtype為資料型別,預設的資料型別是np.int
numpy.random.random_integers(low, high=None, size=None) 返回給定維度的整數array,每個數是閉區間[low,high]或[1,low]均勻分佈整數 該函式在最新的numpy版本中已被替代,建議使用randint函式
numpy.random.choice(a, size=None, replace=True, p=None) (依概率)從給定的一維陣列中(有放回或無放回地)隨機選擇 引數: a為一維陣列類似資料或整數;size為陣列維度;replace:True為有放回,False為無放回;p為陣列中的資料出現的概率
numpy.random.shuffle(x) 原列表上將元素打亂。 與random.shuffle()一樣 x: array or list

產生特定分佈的函式

常用函式示例

numpy.random.seed()

# 第一次 seed = 0
np.random.seed(0)
np.random.rand(5)
>> array([0.5488135 , 0.71518937, 0.60276338, 0.54488318, 0.4236548 ])

# 換一個seed
np.random.seed(1676)
np.random.rand(5)
>> array([0.39983389, 0.29426895, 0.89541728, 0.71807369, 0.3531823 ])

# 第二次 seed = 0,發現結果與第一次一樣,即得到了可復現的隨機數
np.random.seed(0)
np.random.rand(5)
>> array([0.5488135 , 0.71518937, 0.60276338, 0.54488318, 0.4236548 ])

numpy.random.rand()

根據給定維度生成均勻分佈開區間[0,1)之間的數

import numpy as np

# numpy.random.rand
np.random.rand()  # 當沒有引數時,返回單個數據
>> 0.8214199637356738

np.random.rand(4) # shape: 4
>> array([0.28966543, 0.2007679 , 0.87655807, 0.94153647])

np.random.rand(4,2) # shape: 4*2
>> array([[0.05436321, 0.7350782 ],
          [0.52215659, 0.53889898],
          [0.46468492, 0.71335749],
          [0.8038878 , 0.64666693]])

np.random.rand(4,3,2)  # shape: 4*3*2
>> array([[[0.34545913, 0.69313943],
           [0.79446914, 0.87836912],
           [0.65324253, 0.79146979]],

         [[0.62297291, 0.85356693],
          [0.54331809, 0.82817135],
          [0.41794522, 0.38204339]],

         [[0.67268369, 0.25551782],
          [0.71614578, 0.77045723],
          [0.27518846, 0.99426059]],

         [[0.20126485, 0.89100356],
          [0.04855106, 0.72816571],
          [0.50437136, 0.27798907]]])

numpy.random.randn()

返回給定維度的array,每個數服從標準正態分佈

np.random.randn() # 當沒有引數時,返回單個數據
>> -1.1241580894939212

np.random.randn(2,4)
>> array([[ 0.27795239, -2.57882503,  0.3817649 ,  1.42367345],
       [-1.16724625, -0.22408299,  0.63006614, -0.41714538]])

np.random.randn(4,3,2)
>> array([[[ 1.27820764,  0.92479163],
        [-0.15151257,  1.3428253 ],
        [-1.30948998,  0.15493686]],

       [[-1.49645411, -0.27724089],
        [ 0.71590275,  0.81377671],
        [-0.71833341,  1.61637676]],

       [[ 0.52486563, -1.7345101 ],
        [ 1.24456943, -0.10902915],
        [ 1.27292735, -0.00926068]],

       [[ 0.88303   ,  0.46116413],
        [ 0.13305507,  2.44968809],
        [-0.73132153, -0.88586716]]])

numpy.random.randint()

返回隨機整數的array

np.random.randint(1,size=5) # 返回[0,1)之間的整數,所以只有0
>> array([0, 0, 0, 0, 0])

np.random.randint(1,5) # 返回1個[1,5)之間的隨機整數
>> 4

np.random.randint(-5,5,size=(2,2)) # 返回[1,5)之間的隨機整數
>> array([[ 2, -1],
          [ 2,  0]])

numpy.random.random_integers() 即將廢棄

與numpy.random.randint()功能類似。該函式在最新的numpy版本中已被替代,建議使用randint()函式

np.random.random_integers(5,size=5)

__main__:1: DeprecationWarning: This function is deprecated. Please call randint(1, 5 + 1) instead
>> array([2, 4, 3, 4, 2])

生成[0,1)之間均勻分佈的浮點數

print('-----------random_sample()--------------')
print(np.random.random_sample(size=(2,2)))
print('-----------random()--------------')
print(np.random.random(size=(2,2)))
print('-----------ranf()--------------')
print(np.random.ranf(size=(2,2)))
print('-----------sample()--------------')
print(np.random.sample(size=(2,2)))


# 輸出:
-----------random_sample()--------------
[[0.70770026 0.32289658]
 [0.37320026 0.12638252]]
-----------random()--------------
[[0.47976139 0.82591445]
 [0.24703018 0.02357945]]
-----------ranf()--------------
[[0.90345548 0.77388432]
 [0.97383893 0.47288215]]
-----------sample()--------------
[[0.74441927 0.31705026]
 [0.55894275 0.79483591]]

numpy.random.choice()


# 從np.range(5)即0~4的整數中,(預設)有放回地等概率選擇三個數
np.random.choice(5,3)  
>> array([1, 3, 3])

# 無放回地選擇。此時輸出size應小於range
np.random.choice(5, 3, replace=False)
>> array([0, 2, 3])



#從np.range(5)即0~4的整數中,(預設)有放回地選擇3*2維的array陣列
np.random.choice(5,size=(3,2))
>> array([[0, 2],
          [2, 2],
          [1, 4]])

#從列表中有放回地等概率選擇元素,組成3*3維的array陣列
list_ = ['a', 'b','c','d', 'e']
np.random.choice(list_,size=(3,3))
>> array([['c', 'b', 'a'],
          ['b', 'e', 'c'],
          ['d', 'b', 'b']], dtype='<U1')


# 不等概率隨機選取
# 引數p為概率,長度應與引數a一致,p裡的資料之和應為1
np.random.choice(list_,size=(3,3),p=[0.1,0.6,0.1,0.1,0.1])
>> array([['b', 'b', 'a'],
          ['b', 'b', 'b'],
          ['e', 'a', 'b']], dtype='<U1')

numpy.shuffle()

arr = np.arange(9).reshape((3, 3))
np.random.shuffle(arr)

arr
>> array([[3, 4, 5],
          [6, 7, 8],
          [0, 1, 2]])

兩個包的區別

numpy.random比python原生random更靈活,具體如表:

比較內容 原生random numpy.random
輸入型別 非空的列表型別(包括列表、字串和元組) 非空的列表型別(包括列表、字串和元組)+ numpy.array型別
輸出維度 一個數或一個list(多個數) 可指定複雜的size
指定(a,b)範圍 可以 整數可指定,浮點數不行,需自行轉換
批量輸出 不可 可。通過指定size引數
特定分佈 涵蓋了常用的幾個分佈; 只能單個輸出 幾乎涵蓋了所有分佈;可批量輸出
有放回和無放回(選取元素時) sample()無放回選k個;choices()有放回選k個 choice()可有引數來指定有/無放回
不等概率取樣 choices()指定weights引數 choice()指定p引數
shuffle()函式 random.shuffle(x)只支援list numpy.random.shuffle(x)支援array和list

numpy將原生random的sample()和choices()合併為一個numpy.choice()函式。