【问题标题】:Generate array of floats within possible MAX and MIN在可能的 MAX 和 MIN 内生成浮点数组
【发布时间】:2015-03-26 14:40:06
【问题描述】:

我正在尝试生成浮点数,但不在 [0-1) 内,而是在 sys.float_info.maxsys.float_info.min 内。不幸的是,Python 的 random 和 Numpy random 以这种方式工作

a + (b-a) * random()

但是 random() 不会生成足够小的数字来与 MAX 浮点数的指数竞争。

print min([random.uniform(0, sys.float_info.max) for i in range(10000)])
>>2.0237842876e+304

如何生成从 0 - MAX(float) 或 MIN(float) 到 MAX(float) 的浮点数?

【问题讨论】:

  • 分发有什么要求?
  • 均匀分布,如代码中。
  • 我想你误解了均匀分布。回想一下,1E+304 和sys.float_info.max (2E+308) 之间的数字比 0 和 1E+304 之间的数字多约 20,000 个。即因为您选择 0 到 2E+308 之间的 10k 个数字,所以最小值可能在 2E+304 左右。
  • 如果实际上不需要制服,可以使用一些技巧。正如@farenorth 所指出的,在整个范围内对均匀分布进行采样很少会产生适中的值。
  • 另请注意,sys.float_info.min 是 2.22E-308(即非常接近 0),而不是 - sys.float_info.max。换句话说,random.uniform(sys.float_info.min, sys.float_info.max)random.uniform(0, sys.float_info.max) 应该给出几乎相同的结果。

标签: python numpy random floating-point


【解决方案1】:

我们可以查看浮动 sys.float_info.minsys.float_info.maxint64s:

imin = np.float64(sys.float_info.min).view('int64')
imax = np.float64(sys.float_info.max).view('int64')

In [298]: imin, imax
Out[298]: (4503599627370496, 9218868437227405311)

然后我们可以在iminimax 之间生成随机整数,并将它们视为float64s:

In [299]: np.random.random_integers(imin, imax, size=10).view('float64')
Out[299]: 
array([  2.88648634e+084,   3.52929128e+117,   4.92852196e-157,
         1.19367593e+214,   3.72292917e-171,   7.00063144e+121,
         9.06356989e+141,   9.13489394e-054,   1.29622916e-304,
         2.04781344e+064])

随着整数从imin 增加到imax,相应的浮点数也会增加 从sys.float_info.min 增加到sys.float_info.max

float('inf')float('nan')对应的整数位于区间[imin, imax]之外,所以不用担心生成infs或nans。

In [323]: np.arange(imax, imax+5).view('float64')
Out[323]: 
array([  1.79769313e+308,               inf,               nan,
                     nan,               nan])

警告:正如farenorth 指出的那样,可表示为浮点数的数字不是 平均分配。 0 和 1 之间的浮点数比 1 和 2 之间的浮点数多得多,而且比浮点数多得多 大花车之间。因此,下面的方法不会生成 来自均匀分布的随机样本。

【讨论】:

    【解决方案2】:

    我发现在可能的范围内生成任何随机浮点数的最佳方法是生成一个随机字节序列并将其解析为浮点数。

    import os, struct, math
    #float32
    rand_num = struct.unpack('f', os.urandom(4))[0]
    if not math.isnan(rand_num):
      print rand_num
    
    #float64 aka double
    rand_num = struct.unpack('d', os.urandom(8))[0]
    if not math.isnan(rand_num):
      print rand_num
    

    【讨论】:

      【解决方案3】:

      我认为您可以通过加入整数部分和浮点数来简单地生成随机数的两个部分。

      random.uniform(sys.float_info.min, sys.float_info.max) + random.random()
      

      【讨论】:

      • 这是一个聪明的技巧,但 random.random() 没有给出足够小的数字(即e-300)。然后我会得到只有 6-7 分数范围内的数字。
      • 我认为您可以生成足够大的数字,然后将其除以 10 以满足您的需要,但可能我真的不知道您的问题领域。只是一个想法random.randint(0, 10e300)/float(10e300),但不确定浮点数是否在句点后有这么多数字,但是如果您只需要生成数字并在代码之外使用它,则可以使用 random.randint(0, 10e300) 部分
      猜你喜欢
      • 2015-06-05
      • 2011-06-26
      • 1970-01-01
      • 1970-01-01
      • 2010-10-23
      • 2016-05-11
      • 1970-01-01
      • 1970-01-01
      • 2020-08-25
      相关资源
      最近更新 更多