2011-08-11 16 views
62

में numpy.random और random.random के बीच मतभेद मेरे पास पायथन में एक बड़ी स्क्रिप्ट है। मैंने खुद को अन्य लोगों के कोड में प्रेरित किया, इसलिए मैंने कुछ चीजों के लिए numpy.random मॉड्यूल का उपयोग करके समाप्त किया (उदाहरण के लिए एक द्विपदीय वितरण से ली गई यादृच्छिक संख्याओं की एक सरणी बनाने के लिए) और अन्य स्थानों पर मैं मॉड्यूल random.random का उपयोग करता हूं।पायथन

क्या कोई मुझे दोनों के बीच प्रमुख अंतर बता सकता है? दो में से प्रत्येक के लिए डॉक्टर वेबपेज को देखते हुए मुझे लगता है कि numpy.random में अभी और अधिक विधियां हैं, लेकिन मुझे स्पष्ट नहीं है कि यादृच्छिक संख्याओं की पीढ़ी अलग कैसे है।

कारण मैं पूछ रहा हूं क्योंकि मुझे डीबगिंग उद्देश्यों के लिए मेरे मुख्य कार्यक्रम को बीज करने की आवश्यकता है। लेकिन यह तब तक काम नहीं करता जब तक कि मैं आयात करने वाले सभी मॉड्यूल में एक ही यादृच्छिक संख्या जेनरेटर का उपयोग नहीं करता, क्या यह सही है?

इसके अलावा, मैंने यहां एक और पोस्ट में पढ़ा है, numpy.random.seed() का उपयोग न करने के बारे में एक चर्चा, लेकिन मुझे वास्तव में समझ में नहीं आया कि यह इतना बुरा विचार क्यों था। अगर कोई मुझे बताए कि यह मामला क्यों है तो मैं वास्तव में सराहना करता हूं।

उत्तर

75

आपने पहले से ही कई सही अवलोकन किए हैं!

जब तक आप दोनों यादृच्छिक जनरेटर को बीज नहीं करना चाहते हैं, तो यह एक जनरेटर या दूसरे को चुनने के लिए लंबे समय तक संभवतः आसान है। है, नहीं सुरक्षित है क्योंकि यह दो अलग धागे एक ही समय में फ़ंक्शन को निष्पादित कर रहे हैं काम करने के लिए गारंटी नहीं है अगर आप many different threads of execution है उपयोग करने के लिए, कि यह -

numpy.random.seed() के लिए, मुख्य कठिनाई यह है कि यह थ्रेड-सुरक्षित नहीं है । यदि आप धागे का उपयोग नहीं कर रहे हैं, और यदि आप उचित रूप से उम्मीद कर सकते हैं कि भविष्य में आपको इस तरह अपने प्रोग्राम को फिर से लिखना होगा, 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 के लिए उपयुक्त है। लेकिन क्योंकि अनुक्रम बहुत लंबा है, दोनों रोजमर्रा के कार्यक्रमों में यादृच्छिक संख्या उत्पन्न करने के लिए ठीक हैं। यह यादृच्छिक मूल्य के बीज की आवश्यकता के कारण भी है - यदि आप हर बार एक ही स्थान पर शुरू करते हैं, तो आपको हमेशा यादृच्छिक संख्याओं का एक ही अनुक्रम मिल जाएगा!

एक तरफ ध्यान दें, यदि आप क्रिप्टोग्राफिक स्तर अनियमितता की जरूरत है , आप secrets मॉड्यूल, या Crypto.Random की तरह कुछ है, तो आप एक अजगर संस्करण अजगर 3.6 से पहले उपयोग कर रहे हैं का उपयोग करना चाहिए।

+9

एक दूर से संबंधित टिप्पणी के रूप में, यह * न *, का उपयोग करने के बाद से Mersenne ट्विस्टर एन्ट्रापी क्रिप्टोग्राफिक के लिए पर्याप्त के यादृच्छिक दृश्यों का उत्पादन नहीं करता (और कभी कभी आवश्यक है कुछ असामान्य वैज्ञानिक) उद्देश्यों। उन दुर्लभ मामलों में, आपको अक्सर [Crypto.Random] की आवश्यकता होती है (https://www.dlitz.net/software/pycrypto/apidoc/Crypto.Random.random-module.html), जो ओएस विशिष्ट एन्ट्रॉपी स्रोतों का उपयोग करने में सक्षम है अकेले 'random.random' से उपलब्ध की तुलना में बहुत अधिक गुणवत्ता के गैर-निर्धारिती यादृच्छिक अनुक्रम उत्पन्न करने के लिए। हालांकि, आपको आमतौर पर इसकी आवश्यकता नहीं होती है। – SingleNegationElimination

+0

धन्यवाद हनीले। आपकी अंतर्दृष्टि वास्तव में बहुत उपयोगी थी! यह पता चला है कि मैं केवल एक ही यादृच्छिक संख्या जनरेटर का उपयोग करने से दूर नहीं जा सकता, (जो यादृच्छिक होने की आवश्यकता है क्योंकि यादृच्छिक वितरण द्विपक्षीय वितरण नहीं करता है) क्योंकि मेरे प्रोग्राम के कुछ हिस्सों में एक और प्रोग्राम है जो यादृच्छिक उपयोग करता है। मुझे दो जेनरेटर बीज देना होगा। – Laura

+1

"यदि आप जानते हैं कि अब आपके पास कौन सा नंबर है, तो पूर्ण निश्चितता के साथ भविष्यवाणी करना संभव है कि अगला नंबर कौन सा होगा।" मुझे लगता है कि इस कथन को कुछ स्पष्टीकरण की आवश्यकता हो सकती है। इसका मतलब यह है कि यदि आप जनरेटर के * आंतरिक राज्य * को जानते हैं तो आप अनुक्रम को पुन: उत्पन्न कर सकते हैं - जो आप जनरेटर के बीज करते हैं तो आप यही करते हैं। जनरेटर से एक एकल संख्या आउटपुट को देखते हुए आप अगले नंबर की भविष्यवाणी नहीं कर सकते हैं। अवधि इतनी बड़ी है कि आपको छद्म-यादृच्छिक अनुक्रम पर कहां गणना करनी चाहिए और इस प्रकार अगले की भविष्यवाणी करने से पहले आपको संख्याओं के लंबे अनुक्रम की आवश्यकता होगी। –

3

बीज और स्रोत प्रोफाइल का स्रोत आउटपुट को प्रभावित करने जा रहा है - यदि आप क्रिप्टोग्राफिक यादृच्छिकता की तलाश में हैं, तो ओएस से बीजिंग।urandom() को डिवाइस चटर (यानी ईथरनेट या डिस्क) से लगभग वास्तविक यादृच्छिक बाइट मिलेगा (यानी बीएसडी पर/dev/यादृच्छिक)

इससे आपको बीज और इतनी उत्पन्न करने वाली यादृच्छिक संख्याएं उत्पन्न करने से बचाएगा। हालांकि यादृच्छिक कॉल आपको संख्याओं को वितरण के लिए फिट करने की अनुमति देते हैं (जिसे मैं वैज्ञानिक यादृच्छिक नेस कहता हूं - आखिरकार आप जो चाहते हैं वह यादृच्छिक संख्याओं का घंटी वक्र वितरण है,

SO हाँ, छड़ी यादृच्छिक, लेकिन defitniely एक distrubtuion वक्र, या के रूप में यादृच्छिक रूप में आप एक लंबी डिवाइस के बिना प्राप्त कर सकते हैं

+0

बहुत बहुत धन्यवाद पॉल, आपका जवाब वास्तव में उपयोगी था! मैं क्रिप्टोग्राफिक यादृच्छिकता की तलाश नहीं कर रहा हूं, मैं गणितीय मॉडलिंग कर रहा हूं और छद्म यादृच्छिक संख्या मेरे लिए पर्याप्त हैं। यह पता चला है कि मैं एक जेनरेटर से चिपक नहीं सकता क्योंकि मैं चाहता था क्योंकि मुझे द्विपक्षीय वितरण के लिए अजीब की आवश्यकता है और मेरा प्रोग्राम यादृच्छिक उपयोग करने वाले दूसरे प्रोग्राम को कॉल करता है :( – Laura

3

Python for Data Analysis से से, मॉड्यूल numpy.random कुशलता के लिए कार्यों के साथ अजगर random पूरक -। एक जनरेटर के साथ है, लेकिन आप क्या यादृच्छिक निर्णय कई प्रकार के संभाव्यता वितरण से नमूना मूल्यों के पूरे सरणी उत्पन्न करना।

इसके विपरीत, पायथन का अंतर्निहित 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