Я пытаюсь найти лучший способ генерации множества случайных чисел в python. Трудная часть заключается в том, что я не буду знать, сколько цифр мне нужно до выполнения.генерирует большое количество случайных чисел
У меня есть программа, которая использует случайные числа по одному, но это нужно делать много раз.
То, что я пытался до сих пор являются:
- генерации случайных чисел по одному, используя
random.random()
- генерации случайных чисел по одному, используя
np.random.rand()
- генерации случайных чисел в пакете из N, используя
np.random.rand(N)
- генерировать случайные числа в партии N, используя
np.random.rand(N)
, и создавать новую партию после первого использования N (я пробовал две разные реализации и бот h медленнее, чем просто генерация одного числа за раз)
В следующем сценарии я сравниваю первые три из этих методов (как для равномерных, так и для нормально распределенных случайных чисел).
Я не знаю, действительно ли нужна функция p
, но я хотел делать эквивалентные вещи со случайными числами в каждом случае, и это казалось самым простым способом сделать это.
#!/bin/python3
import time
import random
import numpy as np
def p(x):
pass
def gRand(n):
for i in range(n):
p(random.gauss(0,1))
def gRandnp1(n):
for i in range(n):
p(np.random.randn())
def gRandnpN(n):
rr=np.random.randn(n)
for i in rr:
p(i)
def uRand(n):
for i in range(n):
p(random.random())
def uRandnp1(n):
for i in range(n):
p(np.random.rand())
def uRandnpN(n):
rr=np.random.rand(n)
for i in rr:
p(i)
tStart=[]
tEnd=[]
N=1000000
for f in [uRand, uRandnp1, uRandnpN]:
tStart.append(time.time())
f(N)
tEnd.append(time.time())
for f in [gRand, gRandnp1, gRandnpN]:
tStart.append(time.time())
f(N)
tEnd.append(time.time())
print(np.array(tEnd)-np.array(tStart))
Представитель пример вывода этого сценария является временной:
[ 0.26499939 0.45400381 0.19900227 1.57501364 0.49000382 0.23000193]
Первые три числа для однородных случайных чисел на [0,1), а следующие три предназначены для нормально распределенных чисел (mu = 0, sigma = 1).
Для любого типа случайных колебаний наиболее быстрый способ (из этих трех) состоит в том, чтобы сгенерировать все случайные числа сразу, сохранить их в массиве и перебрать по массиву. Проблема в том, что я не буду знать, сколько из этих чисел мне понадобится, пока я не запустил программу.
Что бы я хотел сделать, это генерировать случайные числа большими партиями. Затем, когда я использую все числа в одной партии, я просто перезапущу объект, где они хранятся. Проблема в том, что я не знаю, как это сделать. Одним из решений, которое я придумал, является следующее:
N=1000000
numRepop=4
N1=N//numRepop
__rands__=[]
irand=-1
def repop():
global __rands__
__rands__=np.random.rand(N1)
repop()
def myRand():
global irand
try:
irand += 1
return __rands__[irand]
except:
irand=1
repop()
return __rands__[0]
, но это на самом деле медленнее, чем любой другой вариант.
Если я преобразовать Numpy массив в списке, а затем поп-элементы прочь, я получаю такую же производительность, используя только NumPy для генерации случайных случайных величин поштучно:
__r2__=[]
def repop2():
global __r2__
rr=np.random.rand(N1)
__r2__=rr.tolist()
repop2()
def myRandb():
try:
return __r2__.pop()
except:
repop2()
return __r2__.pop()
Есть ли лучший способ сделать это?
Редактировать: от "better" Я просто имею в виду быстрее.Я также предпочитаю детерминированный (псевдо) случайных чисел
(1) Будьте осторожны с такого рода бенчмаркинг '' '' Возвращает время в секундах с начала эпохи в виде числа с плавающей точкой. Обратите внимание: хотя время всегда возвращается как число с плавающей запятой, не все системы обеспечивают время с лучшей точностью, чем 1 секунду. Хотя эта функция обычно возвращает неубывающие значения, она может вернуть более низкое значение, чем предыдущий вызов, если системные часы были установлены обратно между двумя вызовами. '' '(2) Почему поп, если все, что вам нужно, перемещает индекс для выбора позиции. Нет необходимости удалять объекты. – sascha
Что вы подразумеваете под «лучшим способом»? Есть ли у вас какие-либо другие требования, кроме производительности? Для некоторых целей вам нужны криптографически безопасные случайные числа, или вам может потребоваться больше 32 бит случайности. –
@ Håken Lid by «better» Я просто хочу сказать быстрее – kevin