背景
什麼是 NumPy 呢?
NumPy 這個詞來源於兩個單詞 – Numerical
和Python
。其是一個功能強大的 Python 庫,可以幫助程序員輕鬆地進行數值計算,通常應用於以下場景:
- 執行各種數學任務,如:數值積分、微分、內插、外推等。因此,當涉及到數學任務時,它形成了一種基於 Python 的 MATLAB 的快速替代。
- 計算機中的圖像表示爲多維數字數組。NumPy 提供了一些優秀的庫函數來快速處理圖像。例如,鏡像圖像、按特定角度旋轉圖像等。
- 在編寫機器學習算法時,需要對矩陣進行各種數值計算。如:矩陣乘法、求逆、換位、加法等。NumPy 數組用於存儲訓練數據和機器學習模型的參數。
隨機抽樣
numpy.random 模塊對 Python 內置的 random 進行了補充,增加了一些用於高效生成多種概率分佈的樣本值的函數,如正態分佈、泊松分佈等。
numpy.random.seed(seed=None)
Seed the generator.
seed()
用於指定隨機數生成時所用算法開始的整數值,如果使用相同的seed()
值,則每次生成的隨機數都相同,如果不設置這個值,則系統根據時間來自己選擇這個值,此時每次生成的隨機數因時間差異而不同。
在對數據進行預處理時,經常加入新的操作或改變處理策略,此時如果伴隨着隨機操作,最好還是指定唯一的隨機種子,避免由於隨機的差異對結果產生影響。
離散型隨機變量
二項分佈
numpy.random.binomial(n, p, size=None)
Draw samples from a binomial distribution.
表示對一個二項分佈進行採樣,size
表示採樣的次數,n
表示做了n
重伯努利試驗,p
表示成功的概率,函數的返回值表示n
中成功的次數。
【例】野外正在進行9(n=9)口石油勘探井的發掘工作,每一口井能夠開發出油的概率是0.1(p=0.1)。請問,最終所有的勘探井都勘探失敗的概率?
import numpy as np
import matplotlib.pyplot as plt
from scipy import stats
np.random.seed(20200605)
n = 9
p = 0.1
size = 50000
x = np.random.binomial(n, p, size)
print(np.sum(x == 0) / size) # 0.3897
plt.hist(x)
plt.show()
s = stats.binom.pmf(range(10), n, p)
print(np.around(s, 3))
# [0.387 0.387 0.172 0.045 0.007 0.001 0. 0. 0. 0. ]
【例】模擬投硬幣,投2次,請問兩次都爲正面的概率?
import numpy as np
from scipy import stats
import matplotlib.pyplot as plt
np.random.seed(20200605)
n = 2
p = 0.5
size = 50000
x = np.random.binomial(n, p, size)
print(np.sum(x == 0) / size) # 0.25154
print(np.sum(x == 1) / size) # 0.49874
print(np.sum(x == 2) / size) # 0.24972
plt.hist(x, density=True)
plt.show()
s = stats.binom.pmf(range(n + 1), n, p)
print(np.around(s, 3))
# [0.25 0.5 0.25]
泊松分佈
numpy.random.poisson(lam=1.0, size=None)
Draw samples from a Poisson distribution.
表示對一個泊松分佈進行採樣,size
表示採樣的次數,lam
表示一個單位內發生事件的平均值,函數的返回值表示一個單位內事件發生的次數。
【例】假定某航空公司預定票處平均每小時接到42次訂票電話,那麼10分鐘內恰好接到6次電話的概率是多少?
import numpy as np
from scipy import stats
import matplotlib.pyplot as plt
np.random.seed(20200605)
lam = 42 / 6
size = 50000
x = np.random.poisson(lam, size)
print(np.sum(x == 6) / size) # 0.14988
plt.hist(x)
plt.show()
x = stats.poisson.pmf(6, lam)
print(x) # 0.14900277967433773
超幾何分佈
numpy.random.hypergeometric(ngood, nbad, nsample, size=None)
Draw samples from a Hypergeometric distribution.
表示對一個超幾何分佈進行採樣,size
表示採樣的次數,ngood
表示總體中具有成功標誌的元素個數,nbad
表示總體中不具有成功標誌的元素個數,ngood+nbad
表示總體樣本容量,nsample
表示抽取元素的次數(小於或等於總體樣本容量),函數的返回值表示抽取nsample
個元素中具有成功標識的元素個數。
【例】一共20只動物裏有7只是狗,抽取12只有3只狗的概率(無放回抽樣)。
import numpy as np
from scipy import stats
import matplotlib.pyplot as plt
np.random.seed(20200605)
size = 500000
x = np.random.hypergeometric(ngood=7, nbad=13, nsample=12, size=size)
print(np.sum(x == 3) / size) # 0.198664
plt.hist(x, bins=8)
plt.show()
"""
M 爲總體容量
n 爲總體中具有成功標誌的元素的個數
N,k 表示抽取N個元素有k個是成功元素
"""
x = range(8)
s = stats.hypergeom.pmf(k=x, M=20, n=7, N=12)
print(np.round(s, 3))
# [0. 0.004 0.048 0.199 0.358 0.286 0.095 0.01 ]
連續型隨機變量
均勻分佈
numpy.random.uniform(low=0.0, high=1.0, size=None)
Draw samples from a uniform distribution.
Samples are uniformly distributed over the half-open interval [low, high)
(includes low, but excludes high). In other words, any value within the given interval is equally likely to be drawn by uniform
.
【例】在low到high範圍內,創建大小爲size的均勻分佈的隨機數。
import numpy as np
import matplotlib.pyplot as plt
from scipy import stats
np.random.seed(20200614)
a = 0
b = 100
size = 50000
x = np.random.uniform(a, b, size=size)
print(np.all(x >= 0)) # True
print(np.all(x < 100)) # True
y = (np.sum(x < 50) - np.sum(x < 10)) / size
print(y) # 0.40144
plt.hist(x, bins=20)
plt.show()
a = stats.uniform.cdf(10, 0, 100)
b = stats.uniform.cdf(50, 0, 100)
print(b - a) # 0.4
作爲uniform()
的特列,可以得到[0,1)
之間的均勻分佈的隨機數。
numpy.random.rand(d0, d1, ..., dn)
Random values in a given shape.
Create an array of the given shape and populate it with random samples from a uniform distribution over [0, 1)
.
【例】根據指定大小產生[0,1)之間均勻分佈的隨機數。
import numpy as np
np.random.seed(20200614)
print(np.random.rand())
# 0.7594819171852776
print(np.random.rand(5))
# [0.75165827 0.16552651 0.0538581 0.46671446 0.89076925]
print(np.random.rand(4, 3))
# [[0.10073292 0.14624784 0.40273923]
# [0.21844459 0.22226682 0.37246217]
# [0.50334257 0.01714939 0.47780388]
# [0.08755349 0.86500477 0.70566398]]
np.random.seed(20200614)
print(np.random.uniform()) # 0.7594819171852776
print(np.random.uniform(size=5))
# [0.75165827 0.16552651 0.0538581 0.46671446 0.89076925]
print(np.random.uniform(size=(4, 3)))
# [[0.10073292 0.14624784 0.40273923]
# [0.21844459 0.22226682 0.37246217]
# [0.50334257 0.01714939 0.47780388]
# [0.08755349 0.86500477 0.70566398]]
作爲uniform
的另一特例,可以得到[low,high)
之間均勻分佈的隨機整數。
numpy.random.randint(low, high=None, size=None, dtype='l')
Return random integers fromlow
(inclusive) tohigh
(exclusive).
Return random integers from the “discrete uniform” distribution of the specified dtype in the “half-open” interval [low, high). If high is None (the default), then results are from [0, low).
【例】若high
不爲None
時,取[low,high)之間隨機整數,否則取值[0,low)之間隨機整數。
import numpy as np
np.random.seed(20200614)
x = np.random.randint(2, size=10)
print(x)
# [0 0 0 1 0 1 0 0 0 0]
x = np.random.randint(1, size=10)
print(x)
# [0 0 0 0 0 0 0 0 0 0]
x = np.random.randint(5, size=(2, 4))
print(x)
# [[3 3 0 1]
# [1 1 0 1]]
x = np.random.randint(1, 10, [3, 4])
print(x)
# [[2 1 7 7]
# [7 2 4 6]
# [8 7 2 8]]
正態分佈
numpy.random.randn(d0, d1, ..., dn)
Return a sample (or samples) from the “standard normal” distribution.
【例】根據指定大小產生滿足標準正態分佈的數組(均值爲0,標準差爲1)。
import numpy as np
import matplotlib.pyplot as plt
from scipy import stats
np.random.seed(20200614)
size = 50000
x = np.random.randn(size)
y1 = (np.sum(x < 1) - np.sum(x < -1)) / size
y2 = (np.sum(x < 2) - np.sum(x < -2)) / size
y3 = (np.sum(x < 3) - np.sum(x < -3)) / size
print(y1) # 0.68596
print(y2) # 0.95456
print(y3) # 0.99744
plt.hist(x, bins=20)
plt.show()
y1 = stats.norm.cdf(1) - stats.norm.cdf(-1)
y2 = stats.norm.cdf(2) - stats.norm.cdf(-2)
y3 = stats.norm.cdf(3) - stats.norm.cdf(-3)
print(y1) # 0.6826894921370859
print(y2) # 0.9544997361036416
print(y3) # 0.9973002039367398
還可以指定分佈以及所需參數來進行隨機,例如高斯分佈中的mu和sigma。
numpy.random.normal(loc=0.0, scale=1.0, size=None)
Draw random samples from a normal (Gaussian) distribution.
normal()
爲創建均值爲 loc(mu),標準差爲 scale(sigma),大小爲 size 的數組。
sigma * np.random.randn(...) + mu
【例】
import numpy as np
import matplotlib.pyplot as plt
np.random.seed(20200614)
x = 0.5 * np.random.randn(2, 4) + 5
print(x)
# [[5.39654234 5.4088702 5.49104652 4.95817289]
# [4.31977933 4.76502391 4.70720327 4.36239023]]
np.random.seed(20200614)
mu = 5
sigma = 0.5
x = np.random.normal(mu, sigma, (2, 4))
print(x)
# [[5.39654234 5.4088702 5.49104652 4.95817289]
# [4.31977933 4.76502391 4.70720327 4.36239023]]
size = 50000
x = np.random.normal(mu, sigma, size)
print(np.mean(x)) # 4.996403463175092
print(np.std(x, ddof=1)) # 0.4986846716715106
plt.hist(x, bins=20)
plt.show()
指數分佈
numpy.random.exponential(scale=1.0, size=None)
Draw samples from an exponential distribution.
【例】scale = 1/lambda
import numpy as np
import matplotlib.pyplot as plt
from scipy import stats
np.random.seed(20200614)
lam = 7
size = 50000
x = np.random.exponential(1 / lam, size)
y1 = (np.sum(x < 1 / 7)) / size
y2 = (np.sum(x < 2 / 7)) / size
y3 = (np.sum(x < 3 / 7)) / size
print(y1) # 0.63218
print(y2) # 0.86518
print(y3) # 0.95056
plt.hist(x, bins=20)
plt.show()
y1 = stats.expon.cdf(1 / 7, scale=1 / lam)
y2 = stats.expon.cdf(2 / 7, scale=1 / lam)
y3 = stats.expon.cdf(3 / 7, scale=1 / lam)
print(y1) # 0.6321205588285577
print(y2) # 0.8646647167633873
print(y3) # 0.950212931632136
其它隨機函數
numpy.random.choice(a, size=None, replace=True, p=None)
Generates a random sample from a given 1-D array.
從序列中獲取元素,若a
爲整數,元素取值從np.range(a)
中隨機獲取;若a
爲數組,取值從a
數組元素中隨機獲取。該函數還可以控制生成數組中的元素是否重複replace
,以及選取元素的概率p
。
【例】
import numpy as np
np.random.seed(20200614)
x = np.random.choice(10, 3)
print(x) # [2 0 1]
x = np.random.choice(10, 3, p=[0.05, 0, 0.05, 0.9, 0, 0, 0, 0, 0, 0])
print(x) # [3 2 3]
x = np.random.choice(10, 3, replace=False, p=[0.05, 0, 0.05, 0.9, 0, 0, 0, 0, 0, 0])
print(x) # [3 0 2]
aa_milne_arr = ['pooh', 'rabbit', 'piglet', 'Christopher']
x = np.random.choice(aa_milne_arr, 5, p=[0.5, 0.1, 0.1, 0.3])
print(x) # ['pooh' 'rabbit' 'pooh' 'pooh' 'pooh']
np.random.seed(20200614)
x = np.random.randint(0, 10, 3)
print(x) # [2 0 1]
數據一般都是按照採集順序排列的,但是在機器學習中很多算法都要求數據之間相互獨立,所以需要先對數據集進行洗牌操作。
numpy.random.shuffle(x)
Modify a sequence in-place by shuffling its contents.
This function only shuffles the array along the first axis of a
multi-dimensional array. The order of sub-arrays is changed but
their contents remains the same.
對x
進行重排序,如果x
爲多維數組,只沿第 0 軸洗牌,改變原來的數組,輸出爲None。
【例】洗牌,改變自身內容,打亂順序。
import numpy as np
np.random.seed(20200614)
x = np.arange(10)
np.random.shuffle(x)
print(x)
# [6 8 7 5 3 9 1 4 0 2]
print(np.random.shuffle([1, 4, 9, 12, 15]))
# None
x = np.arange(20).reshape((5, 4))
print(x)
# [[ 0 1 2 3]
# [ 4 5 6 7]
# [ 8 9 10 11]
# [12 13 14 15]
# [16 17 18 19]]
np.random.shuffle(x)
print(x)
# [[ 4 5 6 7]
# [ 0 1 2 3]
# [ 8 9 10 11]
# [16 17 18 19]
# [12 13 14 15]]
numpy.random.permutation(x)
Randomly permute a sequence, or return a permuted range.
If x
is a multi-dimensional array, it is only shuffled along its first index.
permutation()
函數的作用與shuffle()
函數相同,可以打亂第0軸的數據,但是它不會改變原來的數組。
【例】
import numpy as np
np.random.seed(20200614)
x = np.arange(10)
y = np.random.permutation(x)
print(y)
# [6 8 7 5 3 9 1 4 0 2]
print(np.random.permutation([1, 4, 9, 12, 15]))
# [ 4 1 9 15 12]
x = np.arange(20).reshape((5, 4))
print(x)
# [[ 0 1 2 3]
# [ 4 5 6 7]
# [ 8 9 10 11]
# [12 13 14 15]
# [16 17 18 19]]
y = np.random.permutation(x)
print(y)
# [[ 8 9 10 11]
# [ 0 1 2 3]
# [12 13 14 15]
# [16 17 18 19]
# [ 4 5 6 7]]
參考文獻
- https://www.jianshu.com/p/63434ad5ea64
當前活動
我是 終身學習者“老馬”,一個長期踐行“結伴式學習”理念的 中年大叔。
我崇尚分享,渴望成長,於2010年創立了“LSGO軟件技術團隊”,並加入了國內著名的開源組織“Datawhale”,也是“Dre@mtech”、“智能機器人研究中心”和“大數據與哲學社會科學實驗室”的一員。
願我們一起學習,一起進步,相互陪伴,共同成長。
後臺回覆「搜搜搜」,隨機獲取電子資源!
歡迎關注,請掃描二維碼: