φυβλαςのβλογ
phyblas的博客



ฟังก์ชันที่เกี่ยวข้องกับการสุ่มใน python
เขียนเมื่อ 2016/05/08 20:11
แก้ไขล่าสุด 2021/09/28 16:42
โดยทั่วไปแล้วเวลาเขียนโปรแกรมแล้วรันผลที่ได้มักจะต้องเหมือนเดิมตลอด เพราะคอมพิวเตอร์ทำงานอย่างแม่นยำ

แต่ในบางครั้งเราก็อาจจะต้องการให้มีความไม่แน่นอนเกิดขึ้นบ้าง นั่นคือมีการสุ่ม

ภาษา python มีมอดูลที่เก็บฟังก์ชันที่ทำหน้าที่เกี่ยวกับการสุ่มต่างๆไว้โดยเฉพาะ มอดูลนั้นมีชื่อว่า random

ก่อนอื่นต้องทำการเรียกใช้ด้วยการ import
import random

ฟังก์ชันในมอดูลนี้มีอยู่หลายตัว ในที่นี้จะขอแนะนำตัวที่เด่นๆที่น่าจะมีโอกาสได้ใช้บ่อยขึ้นมาให้ได้ทำความรู้จักเอาไว้



random.random
เป็นฟังก์ชันที่คืนค่าสุ่มตั้งแต่ 0 จนถึงไม่เกิน 1 โดยแต่ละค่ามีโอกาสได้เท่ากันหมด

นั่นคือ random.random() จะได้ค่าในช่วง 0 <= x < 1.0
print(['%.2f'%random.random() for i in range(5)])

ผลลัพธ์
['0.82', '0.27', '0.59', '0.92', '0.39']

ลองสุ่มเยอะๆแล้วนำมาทำเป็นฮิสโทแกรมจะเห็นชัดว่าการแจกแจงเท่ากันหมดตั้ง 0 ถึง 1
ranran = [random.random() for i in range(100000)]



ภาพนี้เขียนด้วย matplotlib แต่ขอไม่พูดถึงวิธีการใช้ในที่นี้



random.uniform()
เป็นฟังก์ชันที่สุ่มค่าในช่วงที่กำหนดโดยโอกาสได้แต่ละค่าในช่วงมีเท่ากัน โดย random.uniform(a,b) จะได้ค่าอยู่ในช่วง [a,b] (a <= ค่า <= b) (แต่ถ้า b น้อยกว่า a จะได้ b <= x <= a)

ตัวอย่าง
print(' '.join(['%.2f'%random.uniform(50,100) for i in range(10)]))

ผลลัพธ์
56.71 68.28 51.79 74.74 62.90 83.60 88.95 92.76 71.06 91.67



random.randint
สุ่มค่าจำนวนเต็มในช่วง โดย random.randint(a,b) จะได้ค่าอยู่ในช่วง [a,b] (a <= ค่า <= b)

ตัวอย่าง
print('-'.join(['%d'%random.randint(93,99) for i in range(12)]))

ได้
93-97-99-97-95-96-98-98-98-94-95-96



random.randrange
สุ่มค่าจำนวนเต็มจากในช่วง โดยเหมือนการสุ่มค่าที่ได้จาก range มาตัวหนึ่ง อาร์กิวเมนต์จะเหมือนกับ range นั่นคือ random.randrange(a,b,c)

โดยที่ a คือค่าเริ่มต้น b คือค่าหยุด และ c คือระยะเว้น หากไม่มีได้ใส่ c ก็จะเว้น 1
print('>'.join(['%d'%random.randrange(1,9,2) for i in range(11)]))

ได้
5>5>5>7>1>1>1>5>5>7>5



random.triangular
สุ่มค่าภายในช่วงที่กำหนด โดยที่ตรงกลางช่วงจะมีโอกาสสุ่มได้มากที่สุด และค่อยๆน้อยลงเมื่อห่างจากใจกลาง และเป็น 0 ที่ปลายช่วง โดยการลดลงนั้นเป็นเชิงเส้น

อาร์กิวเมนต์ที่ต้องใส่มี ๒ ตัวคือค่าเริ่มกับค่าปลาย random.triangular(a,b) โดยที่ a และ b คือค่าขอบปลายทั้งสอง อันไหนจะมากกว่าก็ได้

ตัวอย่าง
rantri = [random.triangular(50,100) for i in range(100000)]

เอามาเขียนแผนภูมิแท่งแจกแจงจำนวนก็จะได้เป็นสามเหลี่ยมอย่างชัดเจน โดยใจกลางคือ 75





random.gauss
สุ่มค่าโดยมีความน่าจะเป็นที่จะได้เป็นแบบเกาส์ หรือเรียกว่าการแจกแจงความน่าจะเป็นแบบปกติ คือที่ใจกลางจะมีค่าสูงสุดและค่อยๆน้อยลงเมื่อห่างใจกลาง

อาร์กิวเมนต์ที่ต้องใส่มี ๒ ตัว random.gauss(μ,σ) ในที่นี้ μ คือค่าใจกลาง และ σ คือความกว้างของการกระจาย

ตัวอย่าง
rangau = [random.gauss(75,7.5) for i in range(100000)]

เขียนกราฟจะได้แบบนี้ จะเห็นว่ามีการกระจายที่ดูเป็นธรรมชาติ





random.choice
ในบางครั้งสิ่งที่เราต้องการสุ่มก็อาจไม่ได้มีแค่ตัวเลข แต่ต้องการสุ่มเลือกของบางอย่างจากกลุ่ม

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

แต่มีวิธีที่ง่ายกว่านั้น คือใช้ฟังก์ชัน random.choice ฟังก์ชันนี้จะสุ่มของชิ้นหนึ่งออกมาจากกลุ่มข้อมูล

กลุ่มข้อมูลที่ใช้อาจเป็นลิสต์, ทูเพิล หรือสายอักขระก็ได้
tualueak = 'กขคง'
print([random.choice(tualueak) for i in range(20)])

ผลลัพธ์
['ข', 'ก', 'ค', 'ง', 'ค', 'ก', 'ข', 'ก', 'ก', 'ข', 'ก', 'ก', 'ค', 'ก', 'ข', 'ก', 'ก', 'ข', 'ข', 'ง']



random.sample
เป็นฟังก์ชันที่จะสุ่มหยิบของออกมาจากกลุ่มตามจำนวนที่กำหนด โดยจะหยิบไม่ซ้ำอันกันในแต่ละรอบ

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

ตัวอย่าง ลองจำลองการหยิบไพ่
phai = ['A','2','3','4','5','6','7','8','9','10','J','Q','K']
for i in range(4):
    print(random.sample(phai,5))
    
ผลลัพธ์
['6', '3', '8', '9', '2']
['Q', '7', '4', '6', '2']
['8', 'K', '3', 'J', '7']
['6', 'A', '2', 'Q', '3']



random.shuffle
เป็นฟังก์ชันที่ใช้สลับลำดับของข้อมูล เหมือนการสับไพ่ ชุดข้อมูลที่ถูกใช้ในฟังก์ชันนี้จะถูกเปลี่ยนแปลงการจัดเรียงใหม่หมดแบบสุ่ม

ตัวอย่าง
phai = ['A','2','3','4','5','6','7','8','9','10','J','Q','K']
for i in range(4):
    random.shuffle(phai)
    print(phai)

ผลลัพธ์
['2', '9', '7', 'A', 'J', 'K', '10', 'Q', '4', '5', '6', '3', '8']
['A', '9', '4', 'K', 'Q', 'J', '7', '8', '6', '10', '3', '2', '5']
['7', 'J', 'Q', '3', '10', '8', '4', 'A', '6', '9', '5', 'K', '2']
['K', '3', '8', '10', '5', '9', '6', 'Q', 'J', '4', '2', '7', 'A']



random.seed
บางครั้งเราอาจต้องการให้เลขมีการสุ่มแค่ครั้งเดียวแล้วหลังจากนั้นรันใหม่ก็ ยังอยากให้ได้ผลลัพธ์เหมือนเดิม กรณีนี้สามารถใช้ฟังก์ชัน seed ได้

ฟังก์ชันนี้มีไว้สร้างเมล็ดสำหรับการสุ่มขึ้นมาแล้วเก็บเอาไว้เพื่อให้ได้ค่าเหมือนเดิมทุกครั้ง

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

ใช้คำสั่งนี้ก่อนเริ่มการสุ่มแต่ละครั้งจะพบว่าแต่ละครั้งได้ค่าเดิมตลอด
for j in range(3):
    random.seed(1)
    for i in range(10):
        print(random.randint(0,100), end=' ')
    print()

ผลลัพธ์
17 72 97 8 32 15 63 97 57 60
17 72 97 8 32 15 63 97 57 60
17 72 97 8 32 15 63 97 57 60

ลองรันดูหลายๆรอบจะได้ค่าเดิมตลอด

ลองลบ random.seed(1) ออกแล้วรันใหม่จะพบว่าค่าที่ได้เปลี่ยนไปตลอด

หากต้องการให้มีการสุ่มหลายชุดก็แค่เปลี่ยนอาร์กิวเมนต์ให้หลากหลาย
for k in range(3):
    for j in range(6):
        for i in range(2):
            random.seed((j+k)%4)
            print(random.randint(0,10), end=' ')
    print()

ผลลัพธ์
6 6 2 2 0 0 3 3 6 6 2 2
2 2 0 0 3 3 6 6 2 2 0 0
0 0 3 3 6 6 2 2 0 0 3 3



อ้างอิง


-----------------------------------------

囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧

ดูสถิติของหน้านี้

หมวดหมู่

-- คอมพิวเตอร์ >> เขียนโปรแกรม >> python
-- คอมพิวเตอร์ >> การสุ่ม

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

目录

从日本来的名言
模块
-- numpy
-- matplotlib

-- pandas
-- manim
-- opencv
-- pyqt
-- pytorch
机器学习
-- 神经网络
javascript
蒙古语
语言学
maya
概率论
与日本相关的日记
与中国相关的日记
-- 与北京相关的日记
-- 与香港相关的日记
-- 与澳门相关的日记
与台湾相关的日记
与北欧相关的日记
与其他国家相关的日记
qiita
其他日志

按类别分日志



ติดตามอัปเดตของบล็อกได้ที่แฟนเพจ

  查看日志

  推荐日志

ตัวอักษรกรีกและเปรียบเทียบการใช้งานในภาษากรีกโบราณและกรีกสมัยใหม่
ที่มาของอักษรไทยและความเกี่ยวพันกับอักษรอื่นๆในตระกูลอักษรพราหมี
การสร้างแบบจำลองสามมิติเป็นไฟล์ .obj วิธีการอย่างง่ายที่ไม่ว่าใครก็ลองทำได้ทันที
รวมรายชื่อนักร้องเพลงกวางตุ้ง
ภาษาจีนแบ่งเป็นสำเนียงอะไรบ้าง มีความแตกต่างกันมากแค่ไหน
ทำความเข้าใจระบอบประชาธิปไตยจากประวัติศาสตร์ความเป็นมา
เรียนรู้วิธีการใช้ regular expression (regex)
การใช้ unix shell เบื้องต้น ใน linux และ mac
g ในภาษาญี่ปุ่นออกเสียง "ก" หรือ "ง" กันแน่
ทำความรู้จักกับปัญญาประดิษฐ์และการเรียนรู้ของเครื่อง
ค้นพบระบบดาวเคราะห์ ๘ ดวง เบื้องหลังความสำเร็จคือปัญญาประดิษฐ์ (AI)
หอดูดาวโบราณปักกิ่ง ตอนที่ ๑: แท่นสังเกตการณ์และสวนดอกไม้
พิพิธภัณฑ์สถาปัตยกรรมโบราณปักกิ่ง
เที่ยวเมืองตานตง ล่องเรือในน่านน้ำเกาหลีเหนือ
ตระเวนเที่ยวตามรอยฉากของอนิเมะในญี่ปุ่น
เที่ยวชมหอดูดาวที่ฐานสังเกตการณ์ซิงหลง
ทำไมจึงไม่ควรเขียนวรรณยุกต์เวลาทับศัพท์ภาษาต่างประเทศ