ความแตกต่างระหว่าง numpy.random และ random.random ใน Python


103

ฉันมีสคริปต์ขนาดใหญ่ใน Python ผมได้แรงบันดาลใจตัวเองในรหัสของคนอื่น ๆ ดังนั้นผมจึงจบลงด้วยการใช้numpy.randomโมดูลสำหรับบางสิ่งบางอย่าง (เช่นสำหรับการสร้างอาร์เรย์ของตัวเลขสุ่มนำมาจากการกระจายทวินามเป็นพิเศษ) และในสถานที่อื่น ๆ random.randomที่ฉันใช้โมดูล

ใครช่วยบอกความแตกต่างที่สำคัญระหว่างทั้งสองได้ไหม เมื่อดูที่หน้าเว็บ doc สำหรับทั้งสองดูเหมือนว่าฉันnumpy.randomมีวิธีการมากกว่านี้ แต่ฉันไม่ชัดเจนว่าการสร้างตัวเลขสุ่มนั้นแตกต่างกันอย่างไร

เหตุผลที่ฉันถามคือเพราะฉันต้องการเริ่มต้นโปรแกรมหลักของฉันเพื่อวัตถุประสงค์ในการดีบัก แต่มันไม่ได้ผลเว้นแต่ฉันจะใช้ตัวสร้างตัวเลขสุ่มเดียวกันในทุกโมดูลที่ฉันกำลังนำเข้ามันถูกต้องหรือไม่?

นอกจากนี้ฉันอ่านที่นี่ในโพสต์อื่นการอภิปรายเกี่ยวกับการไม่ใช้numpy.random.seed()งาน แต่ฉันไม่เข้าใจจริงๆว่าทำไมถึงเป็นความคิดที่ไม่ดี ฉันจะขอบคุณมากถ้ามีคนอธิบายว่าทำไมถึงเป็นเช่นนั้น

คำตอบ:


124

คุณได้ทำการสังเกตที่ถูกต้องหลายครั้งแล้ว!

หากคุณไม่ต้องการเริ่มต้นเครื่องกำเนิดไฟฟ้าแบบสุ่มทั้งสองเครื่องอาจจะง่ายกว่าในระยะยาวในการเลือกเครื่องกำเนิดไฟฟ้าเครื่องเดียวหรือเครื่องกำเนิดไฟฟ้าอื่น ๆ แต่ถ้าคุณจำเป็นต้องใช้ทั้งสองอย่างใช่คุณจะต้องเพาะเมล็ดทั้งสองด้วยเพราะมันสร้างตัวเลขสุ่มโดยไม่ขึ้นกัน

สำหรับnumpy.random.seed()ปัญหาหลักคือมันไม่ปลอดภัยสำหรับเธรดนั่นคือไม่ปลอดภัยที่จะใช้หากคุณมีเธรดการดำเนินการที่แตกต่างกันจำนวนมากเนื่องจากไม่รับประกันว่าจะทำงานได้หากเธรดที่แตกต่างกันสองเธรดกำลังเรียกใช้ฟังก์ชันในเวลาเดียวกัน หากคุณไม่ได้ใช้เธรดและหากคุณสามารถคาดหวังได้อย่างสมเหตุสมผลว่าคุณไม่จำเป็นต้องเขียนโปรแกรมของคุณใหม่ด้วยวิธีนี้ในอนาคตnumpy.random.seed()ก็น่าจะดี หากมีเหตุผลที่สงสัยว่าคุณอาจต้องการเธรดในอนาคตจะปลอดภัยกว่าในระยะยาวที่จะทำตามที่แนะนำและเพื่อให้เป็นตัวอย่างของท้องถิ่นnumpy.random.Randomระดับ เท่าที่ฉันสามารถบอกได้ว่าrandom.random.seed()เธรดปลอดภัย (หรืออย่างน้อยฉันก็ไม่พบหลักฐานใด ๆ ในทางตรงกันข้าม)

numpy.randomห้องสมุดมีไม่กี่แจกแจงความน่าจะเป็นพิเศษที่ใช้ในการวิจัยทางวิทยาศาสตร์เช่นเดียวกับคู่ของฟังก์ชั่นอำนวยความสะดวกสำหรับการสร้างอาร์เรย์ของข้อมูลแบบสุ่ม random.randomห้องสมุดเล็ก ๆ น้อย ๆ ที่มีน้ำหนักเบามากขึ้นและควรจะปรับถ้าคุณไม่ได้ทำวิจัยทางวิทยาศาสตร์หรือชนิดอื่น ๆ ของการทำงานในสถิติ

มิฉะนั้นพวกเขาทั้งสองใช้เซนเนทอร์นาโดลำดับเพื่อสร้างตัวเลขสุ่มของพวกเขาและพวกเขาทั้งสองกำหนดสมบูรณ์ - นั่นคือถ้าคุณรู้ว่าบิตสำคัญบางข้อมูลก็เป็นไปได้ที่จะทำนายด้วยความมั่นใจแน่นอนสิ่งที่ตัวเลขจะมาต่อไป ด้วยเหตุนี้ค่า numpy.random มิได้ random.random เหมาะสำหรับการใด ๆ ที่ใช้การเข้ารหัสลับที่ร้ายแรง แต่เนื่องจากลำดับมีความยาวมากทั้งคู่จึงเหมาะสำหรับการสร้างตัวเลขสุ่มในกรณีที่คุณไม่กังวลเกี่ยวกับคนที่พยายามทำวิศวกรรมย้อนกลับข้อมูลของคุณ นี่เป็นสาเหตุของความจำเป็นในการสุ่มค่า - หากคุณเริ่มต้นในสถานที่เดียวกันในแต่ละครั้งคุณจะได้ลำดับตัวเลขสุ่มเหมือนกันเสมอ!

ขณะที่ทราบด้านถ้าคุณไม่ต้องสุ่มระดับการเข้ารหัสลับที่คุณควรใช้ความลับโมดูลหรือสิ่งที่ต้องการCrypto.Randomถ้าคุณกำลังใช้รุ่นก่อนหน้านี้กว่างูหลามงูหลาม 3.6


14
ในฐานะที่เป็นบันทึกที่เกี่ยวข้องอย่างห่าง ๆ บางครั้งก็ไม่จำเป็นที่จะต้องใช้ทั้งสองอย่างเนื่องจาก Mersenne twister ไม่ได้สร้างลำดับเอนโทรปีแบบสุ่มที่เพียงพอสำหรับวัตถุประสงค์ในการเข้ารหัส (และทางวิทยาศาสตร์ที่ผิดปกติ) ในกรณีที่หายากเหล่านี้คุณมักจะต้องใช้Crypto.Randomซึ่งสามารถใช้แหล่งที่มาของเอนโทรปีเฉพาะของระบบปฏิบัติการเพื่อสร้างลำดับสุ่มแบบไม่กำหนดที่มีคุณภาพสูงกว่าที่มีอยู่จากrandom.randomเพียงอย่างเดียว โดยปกติคุณไม่ต้องการสิ่งนี้
SingleNegationElimination

ขอบคุณ Hannnele ข้อมูลเชิงลึกของคุณมีประโยชน์มาก! ปรากฎว่าฉันไม่สามารถหลีกเลี่ยงการใช้เครื่องสร้างตัวเลขสุ่มเพียงตัวเดียวได้ (ซึ่งจำเป็นต้องเป็นตัวเลขเนื่องจากการสุ่มไม่ได้สร้างการแจกแจงทวินาม) เนื่องจากบางส่วนของโปรแกรมของฉันเรียกโปรแกรมอื่นที่ใช้การสุ่ม ฉันจะต้องเพาะเครื่องปั่นไฟทั้งสอง
Laura

2
"ถ้าคุณรู้ว่าตอนนี้คุณมีหมายเลขใดเป็นไปได้ที่จะคาดเดาได้อย่างแน่นอนว่าจะได้หมายเลขอะไรต่อไป ฉันคิดว่าคำพูดนี้อาจต้องการคำชี้แจง ความหมายคือถ้าคุณรู้สถานะภายในของเครื่องกำเนิดไฟฟ้าคุณสามารถสร้างลำดับใหม่ได้ซึ่งเป็นสิ่งที่คุณทำเมื่อคุณวางเครื่องกำเนิดไฟฟ้า ด้วยเอาต์พุตตัวเลขเดียวจากเครื่องกำเนิดไฟฟ้าคุณไม่สามารถคาดเดาหมายเลขถัดไปได้ ช่วงเวลามีขนาดใหญ่มากคุณอาจต้องใช้ลำดับตัวเลขที่ยาวก่อนที่คุณจะสามารถคำนวณได้ว่าคุณอยู่ที่ใดในลำดับสุ่มหลอกจึงทำนายลำดับถัดไป
Kaushik Ghose

12

จากPython สำหรับการวิเคราะห์ข้อมูลโมดูลnumpy.randomเสริม Python randomด้วยฟังก์ชันสำหรับการสร้างอาร์เรย์ทั้งอาร์เรย์ของค่าตัวอย่างจากการแจกแจงความน่าจะเป็นหลายประเภทได้อย่างมีประสิทธิภาพ

ในทางตรงกันข้ามrandomโมดูลในตัวของ Python จะสุ่มตัวอย่างทีละค่าเท่านั้นในขณะที่numpy.randomสามารถสร้างตัวอย่างขนาดใหญ่ได้เร็วขึ้น การใช้ฟังก์ชัน IPython magic %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

1
ไม่ใช่กรณีของวิธีการอื่น เมื่อเทียบnp.random.randint(2)กับrandom.randrange(2)และ NumPy เป็นหนึ่งช้าลง NumPy: 1.25 us และ Random: 891 ns และยังมีความสัมพันธ์ที่เดียวกันและnp.random.rand() random.random()
Shayan Amani

3

แหล่งที่มาของเมล็ดพันธุ์และโปรไฟล์การแจกจ่ายที่ใช้จะส่งผลต่อผลลัพธ์ - หากคุณกำลังมองหาการสุ่มแบบเข้ารหัสการเพาะจาก os.urandom () จะได้รับไบต์แบบสุ่มเกือบจริงจากการพูดคุยของอุปกรณ์ (เช่นอีเธอร์เน็ตหรือดิสก์) (เช่น / dev / สุ่มบน BSD)

สิ่งนี้จะหลีกเลี่ยงไม่ให้คุณให้เมล็ดพันธุ์และสร้างตัวเลขสุ่มแบบดีเทอร์มินิซิทิก อย่างไรก็ตามการโทรแบบสุ่มจะช่วยให้คุณสามารถใส่ตัวเลขให้พอดีกับการแจกแจงได้ (สิ่งที่ฉันเรียกว่า ness แบบสุ่มทางวิทยาศาสตร์ - ในที่สุดสิ่งที่คุณต้องการคือการแจกแจงแบบโค้งระฆังของตัวเลขสุ่ม numpy จะดีที่สุดในการวิเคราะห์สิ่งนี้

ใช่แล้วติดกับเครื่องกำเนิดไฟฟ้าเครื่องเดียว แต่ตัดสินใจว่าคุณต้องการสุ่มอะไร - สุ่ม แต่แยกออกจากเส้นโค้งดิสทรูชันหรือสุ่มเท่าที่คุณจะได้รับโดยไม่ต้องใช้อุปกรณ์ควอนตัม


ขอบคุณมากพอลคำตอบของคุณมีประโยชน์มาก! ฉันไม่ได้มองหาการสุ่มแบบเข้ารหัสฉันกำลังทำแบบจำลองทางคณิตศาสตร์และตัวเลขสุ่มหลอกก็เพียงพอแล้วสำหรับฉัน ปรากฎว่าฉันไม่สามารถยึดติดกับเครื่องกำเนิดไฟฟ้าเครื่องเดียวได้ตามที่ฉันต้องการเนื่องจากฉันต้องการ numpy สำหรับการแจกแจงทวินามและโปรแกรมของฉันเรียกโปรแกรมอื่นที่ใช้การสุ่ม :(
Laura
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.