Python中的隨機數

我在《跟老齊學Python:輕鬆入門》中講述while循環的章節中,設計了一個「猜數遊戲」,在那個遊戲中,讓計算機程序「隨機」生成一個某一範圍內的數字,而後玩家來猜。html

這裏其實暗藏着一個問題:這個遊戲中產生的「隨機數」是否是真的隨機數。python

隨機數(random number),在一個咱們平常都會碰到的領域很是重要:密碼學。通常認爲,密碼學中的隨機數能夠分爲三類(參考:隨機數數組

  1. 僞隨機數
  2. 密碼學安全的僞隨機數
  3. 真隨機數

在密碼學以外,真實的物理環境中,隨機現象也是存在的。好比擲骰子,它所產生的隨機數是「真隨機數」。再好比量子力學中借用蓋格米勒計數器計得的隨機數,也是「真隨機數」。再反觀用計算機程序獲得的隨機數,應該是「僞隨機數」(討論:電腦取隨機數是什麼原理,是真正的隨機數嗎?)。安全

可是,本文要討論的不是密碼學中的隨機數,也不是物理方式獲得的「真隨機數」。本文要討論的就是如何利用Python語言獲得隨機數——本質是「僞隨機數」。框架

random模塊

Python標準庫中有生成隨機數模塊,名爲random——英文:隨機的。dom

>>> import random
>>> dir(random)
['BPF', 'LOG4', 'NV_MAGICCONST', 'RECIP_BPF', 'Random', 'SG_MAGICCONST', 'SystemRandom', 'TWOPI', '_BuiltinMethodType', '_MethodType', '_Sequence', '_Set', '__all__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', '_acos', '_bisect', '_ceil', '_cos', '_e', '_exp', '_inst', '_itertools', '_log', '_os', '_pi', '_random', '_sha512', '_sin', '_sqrt', '_test', '_test_generator', '_urandom', '_warn', 'betavariate', 'choice', 'choices', 'expovariate', 'gammavariate', 'gauss', 'getrandbits', 'getstate', 'lognormvariate', 'normalvariate', 'paretovariate', 'randint', 'random', 'randrange', 'sample', 'seed', 'setstate', 'shuffle', 'triangular', 'uniform', 'vonmisesvariate', 'weibullvariate']
複製代碼

這裏顯示出此模塊的全部函數。下面選擇經常使用項簡要介紹。本文開頭所提到的「猜數遊戲」,程序生成的數字就是100之內的整數,能夠這樣獲得:機器學習

>>> import random
>>> random.randint(0, 99)
21
複製代碼

提醒注意的是,要在100之內的整數中隨機抽取一個數字,在random.randint(0, 99)的參數中,不能寫成(0, 100),它與range(0, 100)的含義不一樣。random.randint中是包含所設置參數的左右邊界的,而range函數不包含所設置參數的右邊界。ide

看來randint在邊界處理上有點非主流。的確是,在Python中的主流是「前包含,後不包含」。其實,就在random模塊中,有一個符合主流思想的,而且能獲得指定範圍隨機整數的函數。函數

>>> random.randrange(0, 99)
41
複製代碼

randrangerandint的第一個不一樣就在於右邊界的處理上,randrange的取值不會包含右邊界。另外,在參數上二者也不一樣。randrange的完整猜數列表是randrange(start, stop=None, step=1),它其實很相似range函數。工具

因此,能夠實現這個示例:隨機生成0到100(含100)間的偶數。

>>> random.randrange(0, 101, 2)
42
複製代碼

除了有可以獲得隨機整數的函數以外,還能夠獲得隨機浮點數。

>>> random.random() 
0.85415370477785668
複製代碼

random()返回0~1之間的一個浮點數,不包含1。

>>> random.uniform(3, 9)
7.4749157626250735
複製代碼

uniform則能夠獲得任意範圍內的隨機浮點數。

在random模塊中,除了生成隨機數以外,還能實現隨機選擇。

>>> random.choice('abcdefg&#%^*f')
'd'
>>> random.choice(['跟老齊學python', '輕鬆入門', '數據分析', 'Django實戰'])
'輕鬆入門'
複製代碼

choice函數的參數是序列,返回從序列中隨機抽取的一個元素——序列不能爲空。

這就相似統計中的隨機抽樣同樣,只不過choice只能抽樣一個,要想實現隨機抽樣若干個,可使用sample函數。

>>> random.sample(['跟老齊學python', '輕鬆入門', '數據分析', 'Django實戰'], 2)
['跟老齊學python', '輕鬆入門']
>>> random.sample(['跟老齊學python', '輕鬆入門', '數據分析', 'Django實戰'], 2)
['跟老齊學python', 'Django實戰']
>>> random.sample(['跟老齊學python', '輕鬆入門', '數據分析', 'Django實戰'], 2)
['輕鬆入門', '數據分析']
複製代碼

sample的參數也是序列,可是後面增長一個數字,指明要抽樣的數量。

以上幾個函數,是處理隨機問題比較經常使用的。若是觀察上面的經過dir(random)獲得的結果,還有不少其餘函數,好比根據特定分佈規律生成隨機數。

>>> random.gauss(0, 1.5)
-1.0137141000649095
複製代碼

不過,不少時候,咱們要的不是一個符合高斯分佈的數值,而是要不少,即一個數據集。因此,還要有新的工具。

Numpy中的隨機數組

在Numpy中,有專門生成隨機數組的函數。

>>> import numpy as np
>>> np.random.random(10)
array([0.00128955, 0.83075305, 0.92794682, 0.52672079, 0.98661054,
       0.61280641, 0.31083683, 0.61955382, 0.01303459, 0.82970689])
複製代碼

np.random.random(size),此函數能夠生成size個元素組成的數組,該數組中的元素是[0, 1)之間隨機獲得的浮點數。此外,參數還能夠是一個元組。

>>> np.random.random((3, 4))
array([[0.94207491, 0.39698129, 0.55712865, 0.60492688],
       [0.85246793, 0.40186698, 0.41727144, 0.34172139],
       [0.49670112, 0.28317277, 0.05541682, 0.24823907]])
複製代碼

在Numpy中,元組表示的是一個數組的形狀,如上面的示例,參數爲(3, 4)就意味着要生成一個3×4的二維數組,而且數組中的元素是隨機地從[1, 0)之間取得的浮點數。注意:關於數組的形狀和軸(本例中0軸方向3個元素、1軸方向4個元素)的有關詳細描述,請參考《跟老齊學Python:數據分析》一書。

與此相似的函數還有:

  • np.random.random_sample

  • np.random.ranf

  • np.random.sample

在Numpy中,還提供了不少根據某種統計分佈生成隨機數的方法。例如:

>>> loc, scale = 0., 1.
>>> s = np.random.laplace(loc, scale, 1000)
>>> s[:10]
array([ 0.77332728, -0.52653062, -1.20956872, -3.10205661, -0.17381902,
       -0.73947538, -0.3925799 ,  3.98593488, -0.74348744, -1.81778326])
複製代碼

如此,獲得了由1000個浮點數組成的一個數組,而且這些數符合拉普拉斯分佈。

能夠用可視化的方式將這些數的分佈展示出來。

>>> import matplotlib.pyplot as plt
>>> count, bins, ignored = plt.hist(s, 30, density=True)
>>> x = np.arange(-8., 8., .01)
>>> pdf = np.exp(-abs(x-loc)/scale)/(2.*scale)
>>> plt.plot(x, pdf)
[<matplotlib.lines.Line2D object at 0x11bf99198>]
>>> plt.show()
objc[57502]: Class FIFinderSyncExtensionHost is implemented in both /System/Library/PrivateFrameworks/FinderKit.framework/Versions/A/FinderKit (0x7fffa589e1d0) and /System/Library/PrivateFrameworks/FileProvider.framework/OverrideBundles/FinderSyncCollaborationFileProviderOverride.bundle/Contents/MacOS/FinderSyncCollaborationFileProviderOverride (0x12a6d6dc8). One of the two will be used. Which one is undefined.
複製代碼

輸出結果: 03-01.png

其它相似函數使用方法與上述闡述相仿,就再也不贅述。更多內容請參考官方文檔:docs.scipy.org/doc/numpy-1…


  • 《跟老齊學Python:輕鬆入門》:面向初學Python的讀物,深刻淺出地講解Python3基礎知識

  • 《跟老齊學Python:Django實戰》:是Python在網站開發方面的書籍,以項目的方式介紹Django框架的應用方式

  • 《跟老齊學Python:數據分析》:是Python在數據分析、機器學習方面的基礎讀物,重點介紹Numpy、Pandas的有關知識和數據可視化的實現方法。

以上書籍,各大網店有售。相關網站:itdiffer.com

相關文章
相關標籤/搜索