1. 程式人生 > 其它 >Numpy隨機陣列(random)

Numpy隨機陣列(random)

numpy.random()模組補充了Python內建random模組的一些功能,用於高效/高速生成一些概率分佈的樣本陣列資料。

In [1]: import numpy as np

In [2]: from random import normalvariate

#從下面比較可以看到,numpy.random模組比Python內建random模組快20多倍
In [4]: %timeit np.random.normal(size=1000000)
31.6 ms ± 1.55 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

In [5]: %timeit samples = [normalvariate(0,1) for i in range(1000000)]
872 ms ± 9.42 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

偽隨機數(peseudorandom numbers)

numpy的隨機數是基於演算法在確定條件下產生的,通過numpy.random.seed()可以設定隨機數生成的種子,以便得到相同的隨機數結果。

#設定全域性的隨機數生成的種子
In [6]: np.random.seed(1234)

#RandomState()用於產生獨立的隨機數生成器
In [7]: rng = np.random.RandomState(1234)

In [8]: rng.randn(10)
Out[8]:
array([ 0.47143516, -1.19097569,  1.43270697, -0.3126519 , -0.72058873,
        0.88716294,  0.85958841, -0.6365235 ,  0.01569637, -2.24268495])

Python內建模組random

In [1]: import random

In [2]: position = 0

In [3]: walks = [position]

In [4]: steps = 1000
#隨機產生一個walks陣列
In [5]: for i in range(steps):
        	# random.randint(0,1)隨機返回整數0或1
   ...:     step = 1 if random.randint(0,1) else -1
   ...:     position += step
   ...:     walks.append(position)
   ...:

In [7]: import matplotlib.pyplot as plt

In [8]: plt.plot(walks)
Out[8]: [<matplotlib.lines.Line2D at 0x14beae2a948>]

In [9]: plt.plot(walks[:100])
Out[9]: [<matplotlib.lines.Line2D at 0x14bf0817648>]

Numpy的random模組

#單個數組
In [11]: import numpy as np
In [12]: import matplotlib.pyplot as plt
    
#在[0,2)之間產生包含1000個整數的一維陣列
In [13]: walks = np.random.randint(0,2,size=1000)
In [14]: walks
Out[14]:
array([1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1,
       0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1,
       0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0,
       1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1,
       1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0,
       1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
       1, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0,
       1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 1, 0,
       0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0,
       1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1,
       1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 0,
       0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0,
       0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1,
       1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0,
       1, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0,
       0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1,
       0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0,
       1, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0,
       1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0,
       1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1,
       1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1,
       0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 1,
       1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1,
       0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0,
       1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0,
       0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1,
       1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0,
       1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1,
       0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0,
       0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1,
       0, 1, 1, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1,
       0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1,
       0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 1, 0,
       0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1,
       0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1,
       1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0,
       1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0,
       0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0,
       1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0,
       1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 0,
       0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1,
       1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0,
       0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1,
       0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1,
       1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0,
       0, 1, 0, 0, 1, 1, 1, 0, 1, 0])

#逐個判定陣列中的元素是否大於0,大於0則用1替換,不大於0則用-1替換
In [18]: walks = np.where(walks > 0,1,-1)

#累加
In [20]: walks = walks.cumsum()

In [22]: plt.plot(walks)
Out[22]: [<matplotlib.lines.Line2D at 0x14bf0920588>]

In [23]: plt.plot(walks)
Out[23]: [<matplotlib.lines.Line2D at 0x14bf04b3888>]

#獲取最小偏離值
In [25]: walks.min()
Out[25]: -6
#獲取最大偏離值
In [26]: walks.max()
Out[26]: 44
#獲取首次偏離遠點大於10的位置(步數)
In [27]: (np.abs(walks) > 10 ).argmax()
Out[27]: 78
#多維陣列生成
In [29]: nwalks = 5000
In [30]: nsteps = 1000
#size=(nwalks,nsteps)表示生成nwalks * nsteps 陣列
In [31]: draws = np.random.randint(0,2,size=(nwalks,nsteps))

In [32]: steps = np.where(draws > 0, 1, -1)

#每一行陣列沿1軸累加
In [33]: walks = steps.cumsum(1)

In [34]: walks
Out[34]:
array([[  1,   2,   1, ...,  -8,  -7,  -6],
       [  1,   0,   1, ..., -66, -67, -66],
       [ -1,   0,  -1, ...,  50,  49,  50],
       ...,
       [  1,   2,   3, ..., -36, -37, -38],
       [  1,   0,  -1, ...,  62,  61,  62],
       [ -1,   0,   1, ...,  10,   9,  10]], dtype=int32)

In [35]: walks.max()
Out[35]: 123

In [36]: walks.min()
Out[36]: -129

#每一行沿1軸判定是否有元素絕對值>=30,有則返回True,無則返回False
In [37]: hits30 = (np.abs(walks) >= 30).any(1)

In [38]: hits30
Out[38]: array([ True,  True,  True, ...,  True,  True, False])

#判定有多少行有元素絕對值>=30
In [39]: hits30.sum()
Out[39]: 3374

#提取元素絕對值>=30的行,並返回每行的首次>=30的元素位置
In [40]: crossing_times = (np.abs(walks[hits30]) >= 30).argmax(1)

In [41]: crossing_times
Out[41]: array([283, 461, 339, ..., 989, 427, 525], dtype=int64)

In [42]: crossing_times.mean()
Out[42]: 503.4712507409603

In [43]: plt.plot(walks)

部分numpy.random.字尾函式功能

函式 說明
seed 確定隨機數生成器的種子
permutation 返回一個序列的隨機排列或返回一個隨機排列的範圍
shuffle 對一個序列就地隨機排列
rand 產生均勻分佈的樣本值
randint 從給定的[a,b)範圍內隨機取整數
randn 產生標準正態分佈的樣本值
binomial 產生二項分佈的樣本值
normal 產生正態(高斯)分佈的樣本值
beta 產生Beta分佈的樣本值
chisquare 產生卡方分佈的樣本值
gamma 產生Gamma分佈的樣本值
uniform 產生在[0,1)中均勻分佈的樣本值