Python [0,1]上均匀分布的随机样本
我们都知道并喜欢Python [0,1]上均匀分布的随机样本,python,numpy,random,probability,Python,Numpy,Random,Probability,我们都知道并喜欢numpy函数random.rand,它“创建给定形状的数组,并使用均匀分布在[0,1)上的随机样本传播它”: 如果我想要在[0,1]上均匀分布的随机样本,我的选项是什么?请注意细微的区别:函数numpy排除1;我想要的函数包括1如果我没有错,您可以用如下方法构建小于1的最大数: import struct m = struct.unpack("d",struct.pack("Q",eval("0b00" + "1"*9 + "0" + "1"*52)))[0] 这似乎是: m
numpy
函数random.rand
,它“创建给定形状的数组,并使用均匀分布在[0,1)
上的随机样本传播它”:
如果我想要在
[0,1]
上均匀分布的随机样本,我的选项是什么?请注意细微的区别:函数numpy
排除1
;我想要的函数包括1
如果我没有错,您可以用如下方法构建小于1的最大数:
import struct
m = struct.unpack("d",struct.pack("Q",eval("0b00" + "1"*9 + "0" + "1"*52)))[0]
这似乎是:
m = struct.unpack("d",'\xff\xff\xff\xff\xff\xff\xef?')[0]
(根据IEEE 754标准)。请查看:
from decimal import Decimal
Decimal(m)
其中打印:
Decimal('0.99999999999999988897769753748434595763683319091796875')
然后,将你的
np.random.rand
除以这个值,你就应该得到你想要的东西。如果我没有错的话,你可以用如下公式构建小于1的最大数:
import struct
m = struct.unpack("d",struct.pack("Q",eval("0b00" + "1"*9 + "0" + "1"*52)))[0]
这似乎是:
m = struct.unpack("d",'\xff\xff\xff\xff\xff\xff\xef?')[0]
(根据IEEE 754标准)。请查看:
from decimal import Decimal
Decimal(m)
其中打印:
Decimal('0.99999999999999988897769753748434595763683319091796875')
然后,将你的
np.random.rand
除以这个值,你应该得到你想要的东西。我之前回答过你的问题(参见我的其他答案);我也发表了一条评论。正如我在评论中所说,我真的认为你不应该在意这一点差异;但也许你可以像那样实现你想要的
获取一个与[1,2]中的IEEE 754数字的位序列相对应的随机整数,而不是[0,1],因为非规范化的数字;将这些位转换为浮点IEEE 754数字;然后减去1。这将起作用,因为IEEE 754中[1,2]中的所有数字都是连续的
# sequence of bit for 1.0
>>> eval("0b00" + "1"*10 + "0"*51 + "0")
4607182418800017408
# sequence of bit for first number after 2.0
>>> eval("0b01" + "0"*10 + "0"*51 + "1")
4611686018427387905
>>> struct.unpack("d",struct.pack("Q",np.random.randint(4607182418800017408,4611686018427387905)))[0]-1
0.9349236864324189
您应该能够得到0和1。但是我不确定两个大整数值之间的整数是否完全一致
清洁功能可以是:
from struct import pack, unpack
import numpy as np
def myrand():
a = unpack("Q",pack("d",1.0))[0] # 1.0
b = unpack("Q",pack("d",np.nextafter(2,3)))[0] # 2.000000000000000444
return unpack("d",pack("Q",np.random.randint(a,b)))[0]-1
但同样,这比其他任何事情都更能证明概念。我之前回答了你的问题(见我的另一个答案);我也发表了评论。正如我在评论中所说,我真的认为你不应该在意这一点差异;但也许你可以像那样实现你想要的 获取一个与[1,2]中的IEEE 754数字的位序列相对应的随机整数,而不是[0,1],因为非规范化的数字;将这些位转换为浮点IEEE 754数字;然后减去1。这将起作用,因为IEEE 754中[1,2]中的所有数字都是连续的
# sequence of bit for 1.0
>>> eval("0b00" + "1"*10 + "0"*51 + "0")
4607182418800017408
# sequence of bit for first number after 2.0
>>> eval("0b01" + "0"*10 + "0"*51 + "1")
4611686018427387905
>>> struct.unpack("d",struct.pack("Q",np.random.randint(4607182418800017408,4611686018427387905)))[0]-1
0.9349236864324189
您应该能够得到0和1。但是我不确定两个大整数值之间的整数是否完全一致
清洁功能可以是:
from struct import pack, unpack
import numpy as np
def myrand():
a = unpack("Q",pack("d",1.0))[0] # 1.0
b = unpack("Q",pack("d",np.nextafter(2,3)))[0] # 2.000000000000000444
return unpack("d",pack("Q",np.random.randint(a,b)))[0]-1
但同样,这比其他任何东西都更能证明概念。在float64中,如果将其包括在内,完美1发生的几率为1/2^52。我的问题是,这真的很重要吗?此外,如果你复制这篇文章,你可能想弄清楚它是否使用了Mersene Twister(本机python实现)或者是一个真正的随机数发生器。哈哈,是的。复制实验结果总是有问题的。我以前试过回答你的问题(见下文)但和其他人一样,我强烈认为你不应该关心这个非常微小的差异。我还认为,如果这种差异对你来说很重要,你知道非规范化浮点数吗?换句话说,在[0,1]中,编码浮点数的密度在任何地方都是不一致的。我不知道Numpy是如何生成随机数的,但这样的事实也可能会让你感到不安。问题是:你为什么特别关心
1.0
被排除在外?在[0.0,1.0]范围内大约有2^62个不同的双精度浮点
random.rand
已经只能生成其中的一小部分,约为500分之一。(从random.rand
中有2^53个可能的输出)再缺少一个可能的输出值真的不会有多大区别。瞧,只要使用[0,1)
range;它在统计上与人工创建的[0,1]无法区分
range range random。在float64中,如果将其包括在内,则完美1发生的几率为2^52分之一。我的问题是,这真的很重要吗?此外,如果您复制这篇文章,您可能会想知道它是否使用了Mersenne Twister(本机python实现)或者是一个真正的随机数发生器。哈哈,是的。复制实验结果总是有问题的。我以前试过回答你的问题(见下文)但和其他人一样,我强烈认为你不应该关心这个非常微小的差异。我还认为,如果这种差异对你来说很重要,你知道非规范化浮点数吗?换句话说,在[0,1]中,编码浮点数的密度在任何地方都是不一致的。我不知道Numpy是如何生成随机数的,但这样的事实也可能会让你感到不安。问题是:你为什么特别关心1.0
被排除在外?在[0.0,1.0]范围内大约有2^62个不同的双精度浮点
random.rand
已经只能生成其中的一小部分,约为500分之一。(从random.rand
中有2^53个可能的输出)再缺少一个可能的输出值真的不会有多大区别。瞧,只要使用[0,1)
range;它在统计上与人工创建的[0,1]无法区分
range random。直观地说,除法后的四舍五入将导致一些其他浮点数被排除在该可能的范围之外,不是吗?但在技术上仍然非常正确。我想我还必须确认numpy.random.rand
实际上包含了这个小于1的最大可能数?这是一种更简单的方法t小于1的最大浮点数为numpy.nextafte