隨機數
在進行實驗或者驗證演算法的時候,常常會需要使用「隨機數」來模擬數據,而 NumPy 提供了許多產生隨機數的方法,不僅可以單純產生隨機小數或整數,也可以根據機率分布的演算法,例如常態分布、對數分布、beta 分布...等來產生隨機數,這篇教學將會介紹 NumPy 的 random 模組。
本篇使用的 Python 版本為 3.7.12,所有範例可使用 Google Colab 實作,不用安裝任何軟體 ( 參考:使用 Google Colab )
什麼是隨機數?
隨機數也稱作亂數,表示一串不規則的隨機數字,在程式語言中,通常是透過一系列的演算法來產生隨機數,所以程式語言所產生的隨機數也稱作「偽隨機數」,雖然看起來毫無規則,但只要知道對應的演算法規則,就能夠反推所產生的隨機數。
如果要產生真正的隨機數,通常會搭配一些外部來源 ( 例如鍵盤行為、網路數據、類比數據、背景輻射...等 ),但這往往只應用於安全性的驗證或一些進階的應用,在一般的狀況下,只需要使用程式所提供的方法產生隨機數,就能滿足大部分隨機數的需求。
NumPy 產生隨機數的方法
NumPy 的 random 模組有下列幾種產生隨機數的方法:
方法 | 說明 |
---|---|
random.random() | 產生指定數量或維度的隨機數 ( 0~1 之間的浮點數 )。 |
random.random_sample() | 等同 random.random()。 |
random.ranf() | 等同 random.random()。 |
random.rand() | 產生指定數量或維度的隨機數 ( 0~1 之間的浮點數 )。 |
random.randn() | 產生指定數量或維度的隨機數 ( 常態分布的浮點數 )。 |
random.randint() | 產生指定數值範圍與數量的隨機整數。 |
random.permutation() | 將原本的陣列資料隨機排列,產生新的陣列。 |
random.shuffle() | 將原本的陣列資料隨機排列,改變原本陣列。 |
random.choice() | 產生指定數量的一維陣列隨機整數。 |
隨機數分布生成演算法 | 列出 NumPy 提供的隨機數分布演算法。 |
random.random()
random.random() 能產生指定數量或維度的隨機數 ( 0~1 之間的浮點數 )。
random.random_sample()、random.ranf() 的用法和 random.random() 完全相同。
from numpy import random
print(random.random()) # 0.4068905682640278
print(random.random(3)) # [0.61705999 0.1028753 0.00849189]
print(random.random((3,2))) # 二維陣列
'''
[[0.86175955 0.0851971 ] [0.23620749 0.61860973] [0.86944478 0.14515473]]
'''
print(random.random((3,2,2))) # 三維陣列
'''
[[[0.38583085 0.27966436] [0.62240807 0.83161681]]
[[0.79261711 0.68208243] [0.97840682 0.22284812]]
[[0.98196351 0.94917006] [0.69809127 0.74838828]]]
'''
random.rand()
random.rand() 能產生指定數量或維度的隨機數 ( 0~1 之間的浮點數 )。
多維度的用法和 random.random() 在括號的表現上略有不同 ( random.rand() 少一層括號 ),其餘用法相同。
from numpy import random
print(random.rand()) # 0.7005789765387292
print(random.rand(3)) # [0.741909 0.13810363 0.78651186] 一維陣列
print(random.rand(3,2)) # 二維陣列
'''
[[0.48278515 0.52290733] [0.04385542 0.58186165] [0.62436663 0.26051134]]
'''
print(random.rand(3,2,2)) # 三維陣列
'''
[[[0.50227547 0.14535769] [0.27471491 0.61848338]]
[[0.37914787 0.0053561 ] [0.12544604 0.10443339]]
[[0.42781305 0.70534284] [0.12455917 0.66684256]]]
'''
random.randn()
random.randn() 能產生指定數量或維度的隨機數 ( 常態分布的浮點數 )。
from numpy import random
print(random.randn()) # 1.4421601737169842
print(random.randn(3)) # [-0.56459336 0.50494251 -0.33503292] 一維陣列
print(random.randn(3,2)) # 二維陣列
'''
[[-0.74830529 0.87249096] [-0.66611804 2.989516 ] [ 1.12876535 0.78771974]]
'''
print(random.randn(3,2,2)) # 三維陣列
'''
[[[ 0.68416542 -1.08254128] [-0.63780613 -0.34407012]]
[[-0.09775197 0.24545264] [ 0.44459631 0.29544603]]
[[ 2.50778709 1.11212665] [ 1.04983518 -0.94384928]]]
'''
random.randint()
random.randint() 能產生指定數值範圍與數量的隨機整數,參數有 low 最低數值、high 最高數值、size 陣列尺寸,如果 low 和 high 只設定一個,另一個會自動使用 0。
from numpy import random
print(random.randint(10)) # 6,產生 0~10 的隨機整數
print(random.randint(10,size=3)) # [7 9 0],產生三個 0~10 的隨機整數
print(random.randint(-10,10,size=3)) # [ 7 -1 8],產生三個 -10~10 的隨機整數
print(random.randint(-10,10,size=(3,3))) # 產生 3x3 的陣列,元素為 -10~10 的隨機整數
'''
[[-4 3 -2]
[ 4 -4 7]
[-5 -2 -3]]
'''
random.permutation()
random.permutation() 會將原本的陣列資料隨機排列,產生新的陣列,如果是多維陣列,不會重排每個維度的元素,只會將第一個維度的項目重新排列。
from numpy import random
a = [1,2,3,4,5,6,7,8,9]
b = random.permutation(a)
print(b) # [8 2 7 5 6 1 3 4 9]
c = [[1,2,3],[4,5,6],[7,8,9]]
d = random.permutation(c) # 只重排第一個維度的項目[
print(d) # [[7 8 9] [1 2 3] [4 5 6]]
e = [[[1,2],[3,3]],[[4,5],[6,6]],[[7,8],[9,9]]]
f = random.permutation(e) # 只重排第一個維度的項目
print(f) # [[[4 5] [6 6]] [[1 2] [3 3]] [[7 8] [9 9]]]
random.shuffle()
random.shuffle() 會將原本的陣列資料隨機排列,改變原本的陣列資料,如果是多維陣列,不會重排每個維度的元素,只會將第一個維度的項目重新排列。
from numpy import random
a = [1,2,3,4,5,6,7,8]
b = [[1,2,3,4],[5,6,7,8]]
c = [[[1,2],[3,4]],[[5,6],[7,8]]]
random.shuffle(a)
random.shuffle(b)
random.shuffle(c)
print(a) # [6, 1, 7, 8, 3, 5, 4, 2]
print(b) # [[5, 6, 7, 8], [1, 2, 3, 4]]
# 只重排第一個維度的項目
print(c) # [[[5, 6], [7, 8]], [[1, 2], [3, 4]]]
# 只重排第一個維度的項目
random.choice()
random.choice() 會產生指定數量的一維陣列隨機整數,參數有 a ( 0~a 的整數區間或其他的陣列資料 )、size 輸出的陣列大小,p 陣列資料的機率分布 ( 加總為 1 ),replace 隨機數是否重複 ( 預設 True )。
下方的最後一個例子,會根據 p 的機率設定,產生對應的隨機數陣列,由於原本陣列的 d 出現機率設定為 0,所以產生的新陣列中就不會出現 d 的字母,出現 b 的機率為 80%,出現 a 或 c 的機率各為 10%。
from numpy import random
# 產生十個一個 0~10 隨機整數
print(random.choice(10)) # 8
# 產生十個 0~10 隨機整數
print(random.choice(10,10)) # [5 6 9 6 3 7 1 6 5 1]
# 產生十個不重複的 0~10 隨機整數
print(random.choice(10,10, replace=False)) # [3 2 6 9 8 5 1 7 0 4]
# 根據機率產生十個 a、b、c、d 組合的隨機數陣列
print(random.choice(['a','b','c','d'],10, p=[0.1,0.8,0.1,0])) # ['c' 'a' 'b' 'b' 'b' 'b' 'b' 'b' 'b' 'b']
NumPy 隨機數分布生成演算法
下方整理了 NumPy 支援的隨機數分布生成演算法,透過特定的演算法,就能產生特定範圍與出現機率的隨機數,方便應用於各種統計學的計算:
生成演算法 | 中文名稱 | 參考 |
---|---|---|
random.normal | 常態分布、高斯分布 | NumPy 官方文件、Wiki |
random.standard_normal | 標準常態分布 | NumPy 官方文件 |
random.power | 冪定律分布 | NumPy 官方文件、Wiki |
random.beta | 貝它分布 | NumPy 官方文件、Wiki |
random.gamma | 伽瑪分布 | NumPy 官方文件、Wiki |
random.binomial | 二項式分布 | NumPy 官方文件、Wiki |
random.chisquare | 卡方分布 | NumPy 官方文件、Wiki |
random.dirichlet | 狄利克雷分布 | NumPy 官方文件、Wiki |
random.exponential | 指數分布 | NumPy 官方文件、Wiki |
random.standard_exponential | 標準指數分布 | NumPy 官方文件 |
random.f | F-分布 | NumPy 官方文件、Wiki |
random.geometric | 幾何分布 | NumPy 官方文件、Wiki |
random.gumbel | 甘別分布 | NumPy 官方文件、Wiki |
random.hypergeometric | 超幾何分布 | NumPy 官方文件、Wiki |
random.laplace | 拉普拉斯分布 | NumPy 官方文件、Wiki |
random.logistic | 邏輯分布 | NumPy 官方文件、Wiki |
random.lognormal | 對數常態分布 | NumPy 官方文件、Wiki |
random.logseries | 對數分布 | NumPy 官方文件、Wiki |
random.multinomial | 多項分布 | NumPy 官方文件、Wiki |
random.multivariate_normal | 多元常態分布 | NumPy 官方文件、Wiki |
random.negative_binomial | 負二項式分布 | NumPy 官方文件、Wiki |
random.noncentral_chisquare | Noncentral chi-squared 分布 | NumPy 官方文件、Wiki |
random.noncentral_f | Noncentral F 分布 | NumPy 官方文件、Wiki |
random.pareto | 柏拉圖分布 | NumPy 官方文件、Wiki |
random.poisson | 卜瓦松分布 | NumPy 官方文件、Wiki |
random.rayleigh | 瑞利分布 | NumPy 官方文件、Wiki |
random.standard_cauchy | 標準柯西分布 | NumPy 官方文件、Wiki |
random.standard_t | 司徒頓 t 分布 | NumPy 官方文件、Wiki |
random.triangular | 三角形分布 | NumPy 官方文件、Wiki |
random.uniform | 連續型均勻分布 | NumPy 官方文件、Wiki |
random.vonmises | von Mises 分布 | NumPy 官方文件、Wiki |
random.wald | 逆高斯分布 | NumPy 官方文件、Wiki |
random.weibull | 韋伯分布 | NumPy 官方文件、Wiki |
random.zipf | 齊夫定律分布 | NumPy 官方文件、Wiki |
意見回饋
如果有任何建議或問題,可傳送「意見表單」給我,謝謝~