使用python我正在使用random.randint(0,1)随机生成0或1。不过这很慢,因为我需要做大约十亿次。有更快的方法吗?
total=0
n=1000000000
for x in range(n):
money=2
while True:
x=random.randint(0,1)
if x==1:
break
if x==0:
money*=2
continue
total+=money
print(total/n)
答案 0 :(得分:4)
正如已经评论过的那样,无论如何,在纯Python中这都会有些慢。
但是普通的random.random()
(尽管random.randint()
是基于[0.0, 1.0)
构建的,尽管具有令人惊讶的复杂性)已经返回了0.0到1.0之间的浮点值(或更准确地说,在{{ 1}}),因此,如果您想要一个具有合理稳定分布的随机二进制值,可以执行
from random import random # Avoiding the module attribute access on each loop will save some time
...
if random() < 0.5:
# do one thing
else:
# do the other
我认为即使对于1e9循环,这也是可以接受的。否则,您可以尝试使用Cython。
答案 1 :(得分:2)
一种更快的解决方案是使用random.getrandbits(1)
顺便说一句,如果您想知道您的资金循环是否会收敛到特定的值,那就不会。您进行的采样次数越多,平均数字就越高,尽管在每次运行之间差异很大,尤其是在循环次数较少的情况下。
每次迭代都有50%的机会返回2、25%的机会返回4、12.5%的机会返回8,依此类推...
数学上的期望值可以表示为一个序列(不收敛):
∑ 2 * 1/2 + 4 * 1/4 + 8 * 1/8 .... == ∑ 2 ^ p / 2 ^ p == 1 +1 + 1 + ...
换句话说,随着您采样次数的增加,平均值的变化总和会越来越大。
由于您没有进行无数次尝试,因此您将获得实际的数字。上述系列中2(p)的每个幂将平均为1,直到2 ^ p> n。然后,较高功率的期望值将开始下降。
例如,对于2 ^ 30(约1000000000),您将获得前30次2的幂的平均值1。然后,对于2 ^ 31,将得到0.5,对于2 ^ 32,将得到0.25,依此类推。这将在前30个顶部加起来大约为2。因此,理论上,n = 2 ^ 30的平均值应该接近32。
更一般而言,这应该平均为2 + log(n,2),进展并不很快,但 仍将达到无穷大。
例如:
小样本上会有差异,因为两个高次方的异常值将被随机击中,并对平均值产生重大影响。当样本数量较大时,这些离群值的影响不太明显。
如果您要查找的是一种生成具有指数分布的值的方法,则可能需要尝试random.expovariate()并将其值用作2的指数。
答案 2 :(得分:2)
在Linux上,您可以阅读var patch_size = 37;
var NBands = ee.Number(image.bandNames().length()).getInfo();
Export.image.toCloudStorage({
image: image.toArray(),
description: outFileName,
bucket: 'landsat',
scale: scale,
region: geometry,
fileFormat: 'TFRecord',
formatOptions: {
patchDimensions: [patch_size, patch_size],
tensorDepths: [NBands],
compressed: true
}
});
:
/dev/urandom
打印(在我的旧笔记本电脑i3-3110上,ubuntu 16.04):
from random import randint, getrandbits, random
from timeit import timeit
from operator import and_
from itertools import starmap
f_in = open('/dev/urandom', 'rb')
def generate_num1(n):
return starmap(and_, zip(f_in.read(n), [1]*n))
def generate_num2(n):
return (randint(0, 1) for _ in range(n))
def generate_num3(n):
return (getrandbits(1) for _ in range(n))
def generate_num4(n):
return (1 if random() < 0.5 else 0 for _ in range(n))
print(timeit(lambda: list(generate_num1(1024)), number=1000))
print(timeit(lambda: list(generate_num2(1024)), number=1000))
print(timeit(lambda: list(generate_num3(1024)), number=1000))
print(timeit(lambda: list(generate_num4(1024)), number=1000))
这3个选项中的每一个都比0.11714126999140717
1.9653857139928732
0.20527600098284893
0.1918482400069479
快得多。 random.randint
似乎最快。
答案 3 :(得分:1)
您可以使用numpy有效地做到这一点。有关numpy随机功能的更多信息,请参见:(link)。这将返回一个numpy数组,并带有结果随机序列。
In [1]: import numpy as np
np.random.randint(low=0, high=1, size=1000000000)
Out[2]: array([0, 0, 0, ..., 0, 0, 0])
或者,您可以按以下方式使用randbits:
In [1]: from random import getrandbits
nums = [not random.getrandbits(1) for i in range(0,100000)]
Out[2]: [False,True,...,False]
答案 4 :(得分:0)
这是使用numpy +迭代器的解决方案:
我不确定您的速度如何,但是执行此过程需要6 +/- 0.5秒。
import numpy as np
np.random.seed(11)
n=0
total=0
while n<10**9:
# 10**5 seems to be the golden number here
n_vals = np.random.randint(0,2, 10**5)
n+=10**5
# The prevalence of zeros shouldn't be diff than that of ones
n_zeros = len(n_vals) - np.sum(n_vals)
# square the value of money
total += n_zeros*2
print(total/n)
# 1.000063652