2011-08-11 92 views
62

我在Python中有一個很大的腳本。我在其他人的代碼中激發了我自己,所以我最終使用了numpy.random模塊來完成某些事情(例如,創建一個從二項分佈中獲取的隨機數組),而在其他地方我使用模塊random.randomPython中的numpy.random和random.random之間的區別

有人能告訴我兩者之間的主要區別嗎? 看看這兩個文檔的網頁,在我看來,numpy.random只是有更多的方法,但我不清楚隨機數的產生方式是不同的。

我問的原因是因爲我需要爲我的主程序進行種子調試。但是它不起作用,除非我在我導入的所有模塊中使用相同的隨機數生成器,這是正確的嗎?

此外,我在另一篇文章中閱讀了關於不使用numpy.random.seed()的討論,但我不明白爲什麼這是一個糟糕的主意。如果有人向我解釋爲什麼會出現這種情況,我會很感激。

回答

75

你已經做了很多正確的觀察!

除非你想種兩個隨機發生器,否則從長遠來看選擇一個發生器或其他發生器可能會更簡單。

對於numpy.random.seed(),主要難點在於它不是線程安全的 - 也就是說,如果您有many different threads of execution,則不安全,因爲如果兩個不同的線程同時執行該函數。如果你不使用線程,並且如果你可以合理地預期你將不需要以這種方式重寫你的程序,numpy.random.seed()應該沒問題。如果有任何理由懷疑您未來可能需要線程,從長遠角度來看,按照建議進行操作要更安全,並且要到make a local instance of the numpy.random.Random class。據我所知,random.random.seed()是線程安全的(或至少,我沒有找到任何相反的證據)。

numpy.random庫包含一些常用於科學研究的額外概率分佈,以及一些用於生成隨機數據陣列的便利函數。 random.random函數庫稍微輕量一些,如果您不進行科學研究或其他統計工作,應該沒問題。

否則,它們都使用Mersenne twister sequence來生成它們的隨機數,它們都是完全確定性的 - 也就是說,如果您知道幾個關鍵位的信息,則可以絕對肯定地預測what number will come next。出於這個原因,任何一個都不適用於任何serious cryptographic uses。但是因爲序列非常長,所以在日常程序中都可以生成隨機數。這也是產生隨機值的必要性的原因 - 如果你每次都在同一個地方開始,你總會得到相同的隨機數序列!

作爲一個側面說明,如果你需要的加密級別的隨機性,你應該如果你使用比Python 3.6更早的Python版本使用secrets模塊,或者類似的東西Crypto.Random

+9

作爲一個遠親音符,它有時neccesary *既不是*使用,因爲梅森捻線機不產生熵足夠的加密的隨機序列(和一些不尋常的科學)目的。在這些罕見的情況下,您經常需要[Crypto.Random](https://www.dlitz.net/software/pycrypto/apidoc/Crypto.Random.random-module.html),它可以使用特定於操作系統的熵源生成非確定性的隨機序列,其質量遠高於僅從random.random獲得的質量。不過你通常不需要這個。 – SingleNegationElimination

+0

謝謝你Hannnele。你的見解非常有用!事實證明,我不能逃脫只使用一個隨機數字生成器,(因爲隨機不會產生二項分佈,所以它必須是numpy),因爲我的程序的一部分調用另一個使用隨機的程序。我將不得不種下兩臺發電機。 – Laura

+1

「如果你知道你現在擁有哪個號碼,那麼可以絕對確定接下來會接下來的號碼。」我認爲這個聲明可能需要一些澄清。意思是,如果你知道發電機的內部狀態*,你可以重現序列 - 這就是你在發電機發電時所做的事情。給定發電機的單個數字輸出,您無法預測下一個數字。這個週期非常大,在計算僞隨機序列的位置並預測下一個序列之前,可能需要很長的數字序列。 –

3

種子的來源和使用的分佈配置文件將會影響輸出 - 如果你正在尋找密碼隨機性,從os播種。urandom()將從設備chatter(即以太網或磁盤)(即BSD上的/ dev/random)獲得幾乎真正的隨機字節。

這將避免您給出種子並生成決定性隨機數。然而隨機通話則允許你將數字擬合成一個分佈(我稱之爲科學隨機性 - 最終你想要的是一個隨機數的鐘形曲線分佈,numpy最好是在去除這個數字。一個發電機,但決定你想要什麼隨機 - 隨機的,而是defitniely從distrubtuion曲線,或隨機的,因爲你可以不量子器件

+0

非常感謝Paul,你的回答非常有用!我不是在尋找密碼隨機性,我正在做數學建模,僞隨機數對我來說已經足夠了。事實證明,我不能堅持一個發電機,因爲我需要numpy的二項分佈和我的程序調用另一個程序,使用隨機:( – Laura

3

Python for Data Analysis,模塊numpy.random補充了Python random與功能有效。從多種概率分佈生成整個樣本值數組。相比之下,Python內置的random模塊一次僅採樣一個值,而numpy.random可以更快地生成非常大的採樣。使用IPython的神奇功能%timeit一個可以看到哪些模塊執行速度更快:

In [1]: from random import normalvariate 
In [2]: N = 1000000 

In [3]: %timeit samples = [normalvariate(0, 1) for _ in xrange(N)] 
1 loop, best of 3: 963 ms per loop 

In [4]: %timeit np.random.normal(size=N) 
10 loops, best of 3: 38.5 ms per loop