فهرست بستن

ریزه‌کاری‌های تولید اعداد تصادفی با استفاده از Numpy در پایتون

بسیاری از تحلیل‌های عددی نیاز به تولید اعداد تصادفی دارند. تعداد زیادی از الگوریتم‌ها نیز وجود دارند که برای ارائه راه حل اقدام به ایجاد پاسخ‌های تصادفی برای مسئله و بهبود آن‌ها می‌نمایند. برای همین هم ایجاد اعداد تصادفی یکی از ملزومات شبیه‌سازی‌های علمی می‌باشد. در این نوشته به معرفی امکانات کتابخانه numpy برای تولید اعداد تصادفی پرداخته خواهد شد.

بسم الله الرحمن الرحیم

در این نوشته ما به بررسی امکانات موجود در ماژول random از کتابخانه numpy خواهیم پرداخت. برای این کار ابتدا مروری اجمالی بر توابع و کلاس‌های موجود در این ماژول می‌نماییم:

  • تابع rand: یک آرایه numpy تصادفی در ابعاد داده شده برمی‌گرداند. خروجی بین صفر و یک خواهد بود.
  • تابع randn: یک آرایه numpy تصادفی با توزیع احتمالاتی نرمال در ابعاد داده شده برمی‌گرداند. خروجی
  • تابع randint: یک آرایه numpy تصادفی از نوع عدد صحیح در ابعاد داده شده برمی‌گرداند. اعداد صحیح تصادفی بازگردانده شده در بازه مشخص شده توسط کاربر خواهند بود.
  • تابع random: یک آرایه numpy تصادفی در ابعاد داده شده برمی‌گرداند. اعداد بازگردانده شده در بازه اعداد بین صفر و یک (خود یک نه) خواهند بود.
  • تابع shuffle: یک دنباله را مخلوط می‌نماید و عناصر دنباله در موقعیت‌های تصادفی جدید خواهند بود.
  • تابع permutation: یک دنباله را به‌طور تصادفی جابجا می‌نماید. درصورتی که ورودی یک عدد باشد، خروجی تابع یکی سری تصادفی از اعداد صفر تا عدد داده شده خواهد بود.

برای روشنتر شدن موضوع توابع فوق در مثال‌هایی مورد استفاده قرار خواهند گرفت. در اولین مثال ما به دنبال ایجاد سه دنباله از اعداد تصادفی با توزیع یکنواخت در بازه اعداد بین سه و پنج هستیم:

from numpy import random
import matplotlib.pyplot as plt

N = 25
y = 3 + 2 * random.rand(N, 3)

plt.figure(figsize=(9,3))
plt.plot(y)
plt.grid(True)
plt.legend(["Random series 1", 
            "Random series 2", 
            "Random Series 3"], loc="upper right")
plt.show()

برای اینکار ما می‌توانیم از تابع rand استفاده نماییم. خروجی این تابع در بازه بین صفر و یک می‌باشد ولی هدف ما ایجاد اعداد تصادفی در بازه بین سه و پنج است. طول این بازه برابر دو است و ابتدای بازه عدد سه می‌باشد. لذا ما خروجی تابع rand را در دو ضرب کرده و بعلاوه سه می کنیم. در این صورت اعداد تصادفی به بازه سه تا پنج منتقل خواهند گردید.

خب در ادامه فرض کنید می‌خواهیم یک سری اعداد تصادفی با توزیع نرمال ایجاد نماییم که دارای میانگین a و انحراف معیار b باشند. برای اینکار می‌توانیم از تابع randn استفاده نماییم. کد زیر را در نظر بگیرید:

from numpy import random
import matplotlib.pyplot as plt

N = 25
a = 5.
b = 2.
var = b ** 2
y = a + var * random.randn(N, 3)

plt.figure(figsize=(9,3))
plt.plot(y)
plt.grid(True)
plt.legend(["Random series 1", 
            "Random series 2", 
            "Random Series 3"], loc="upper right")
plt.show()

خروجی این کد به شکل زیر خواهد بود:

حال سراغ استفاده از تابع randint می‌رویم. همانطور که گفته شد این تابع برای تولید اعداد صحیح تصادفی بکار می‌رود. ورودی‌های این تابع برابر محدوده پایین و بالای اعداد صحیح تصادفی و ابعاد بردار تصادفی خروجی می‌باشد. مثال زیر یک سری اعداد تصادفی صحیح ایجاد می‌نماید که در بازه چهار تا ده می‌باشند. دقت کنید که محدوده پایین می‌تواند در خروجی ظاهر شود ولی محدوده بالا خیر.

from numpy import random, linspace
import matplotlib.pyplot as plt

N = 25
y = random.randint(low=4, high=10, size=(N, ))

plt.figure(figsize=(9,3))
plt.stem([i for i in range(1, N+1)], y, use_line_collection=True)
plt.grid(True)
plt.legend(["Random series"], loc="upper right")
plt.show()

خروجی به شکل زیر خواهد بود:

تابع بعدی که مورد بررسی قرار خواهد گرفت تابع random می‌باشد. این تابعی عملکردی مشابه با rand دارد با این تفاوت که ابعاد آرایه خروجی به شکل یک چندتایی باید به تابع داده شود. تابع دیگر shuffle می‌باشد و همانطور که از اسمش پیدا است برای به هم زدن ترتیب یک دنباله از عناصر به کار می‌رود. مثال زیر عملکرد این تابع را بیشتر آشکار می‌سازد:

from numpy import random, linspace
import matplotlib.pyplot as plt

letters = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", 
           "m", "n", "o", "p", "q", "r", "s", "t", "u", "x", "y", "z"]


print(letters)
random.shuffle(letters)
print(letters)

خروجی این مثال به شکل زیر خواهد بود:

['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'x', 'y', 'z']

['o', 'q', 't', 'f', 'z', 'c', 'a', 's', 'r', 'p', 'j', 'y', 'n', 'm', 'h', 'e', 'g', 'l', 'u', 'i', 'x', 'k', 'd', 'b']

همانطور که مشاهده می‌شود، ترتیب عناصر لیست بطور تصادفی تغییر کرده است. تابع نهایی در این قسمت permutation می‌باشد. این تابع نیز عملکردی شبیه به تابع shuffle دارد با این تفاوت که خروجی در خود دنباله داده شده به عنوان ورودی ذخیره نمی گردد بلکه بازگردانده می شود. همچنین در صورتی که ورودی تابع permutation یک عدد صحیح باشد، خروجی آن لیستی از اعداد صفر تا عدد داده شده است که با ترتیب تصادفی در لیست قرار گرفته اند. مثال زیر را مشاهد نمایید:

from numpy import random, linspace
import matplotlib.pyplot as plt

letters = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", 
           "m", "n", "o", "p", "q", "r", "s", "t", "u", "x", "y", "z"]


print(letters)
print(random.permutation(letters))
print(random.permutation(10))

خروجی این مثال نیز به شکل زیر خواهد بود:

['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'x', 'y', 'z']

['n' 'l' 'g' 'z' 'f' 'r' 'h' 'p' 'x' 'o' 'b' 'm' 't' 'e' 's' 'k' 'q' 'c' 'u' 'a' 'i' 'j' 'd' 'y']

[۰ ۹ ۷ ۸ ۱ ۴ ۵ ۶ ۲ ۳]

لازم به ذکر است با اینکه در مثال قبل ورودی تابع permutation یک لیست از کاراکترها بود ولی خروجی آن یک آرایه از نوع str32 می‌باشد. در ادامه به معرفی برخی قابلیت‌های دیگر ماژول random از numpy پرداخته می‌شود.

توزیع‌های احتمالاتی ارائه شده در random که از طریق آن‌ها می‌توان به استخراج نمونه‌های تصادفی پرداخت به شرح زیر می‌باشند:

  • توزیع بتا beta
  • توزیع گاما gamma
  • توزیع دوجمله‌ای binomial
  • توزیع دیریکلیه dirichlet
  • توزیع نمایی exponential
  • توزیع لاپلاس laplace
  • توزیع پواسون poisson
  • توزیع ریلی rayleigh
  • توزیع یکنواخت uniform

افزون بر موارد ذکر شده توزیع‌های احتمالاتی دیگری نیز از طریق ماژول numpy در دسترس می‌باشد. برای مثال سه سری نمونه تصادفی با توزیع احتمالی دیریکلیه ایجاد می‌نماییم. برای استفاده از توزیع‌های احتمالاتی دیگر نیز ابتدا باید ورودی‌ها و پارامترهای آن‌ها را مطالعه نماییم و سپس طبق مثال عمل نماییم. تنها پارامتر مورد نیاز برای توزیع دیریکلیه (به غیر از تعداد نمونه‌هایی که می‌خواهیم داشته باشیم) پارامتر آلفا می‌باشد. چون ما سه سری نمونه تصادفی می‌خواهیم ایجاد نماییم برای همین سه آلفا به عنوان ورودی ارائه خواهیم کرد. آلفا پارامتر اول dirichlet می‌باشد و پارامتر دوم سایز است.

from numpy import random
import matplotlib.pyplot as plt

N = 25
y = random.dirichlet((10, 5, 3), N)

plt.figure(figsize=(9,3))
plt.plot(y)
plt.grid(True)
plt.legend(["Random series 1", 
            "Random series 2", 
            "Random Series 3"], loc="upper right")
plt.show()

خروجی مثال بالا به صورت زیر خواهد بود:

برای اطلاعات تکمیلی در مورد امکانات ماژول random می‌توانید به آدرس زیر مراجعه نمایید:

https://numpy.org/doc/stable/reference/random/index.html