【问题标题】:How do I clip a floating-point number to just below a limit?如何将浮点数剪辑到刚好低于限制?
【发布时间】:2012-03-13 10:52:31
【问题描述】:

numpy.random.uniform() 这样的函数返回两个边界之间的浮点值,包括第一个边界,但不包括顶部。也就是说,numpy.random.uniform(0,1) 可能会产生 0,但永远不会产生 1。

我正在获取这些数字并使用有时会返回超出范围的结果的函数来处理它们。我可以使用 numpy.clip() 将范围之外的值切回 0-1,但不幸的是,该限制包含的最高数字。

如何在python中指定“无限小于1的数”?

【问题讨论】:

  • 如果要相信数学,你就不能。
  • 在大多数系统中都有一个epsilon的概念,它是最小的增量
  • 呃-哦,我能感觉到0.99999... < 1的火焰战争正在酝酿中
  • 我不认为我处于悖论(或火焰战争)领域。或者你是说numpy.random.uniform(0,1) 实际上有时会返回一个等于 1 的数字?如果是这样的话,好吧,好吧。我并不真正关心这个悖论,但我希望我的修改后剪辑的数字能够保证在与原始数字相同的范围内。
  • 我认为 wim 指的是实数 0.9999...(重复)在数学中实际上正好是 1。浮点数不是实数,因此它与您的问题并不特别相关。但是,我将借此机会记录uniform(x,y) 可能(非常罕见!)给您的结果等于y 的情况。 uniform(0,1) 不应该发生这种情况,但在其他情况下,用于将底层 [0,1) 随机数重新缩放到您的界限的浮点算法有时可能会准确地给出 y

标签: python numpy floating-point clipping


【解决方案1】:

好吧,如果你使用的是 numpy,你可以简单地使用numpy.nextafter

>>> import numpy
>>> numpy.nextafter(1, 0)
0.99999999999999989

请注意(至少对我而言):

>>> import sys
>>> 1-sys.float_info.epsilon
0.9999999999999998
>>> numpy.nextafter(1, 0) - (1-sys.float_info.epsilon)
1.1102230246251565e-16
>>> numpy.nextafter(1, 0) > (1-sys.float_info.epsilon)
True

顺便说一下,第二个@Robert Kern 的观点是,有时 random.uniform 包含一些输入的上限,而不是 (0, 1):

>>> import random, numpy
>>> numpy.nextafter(0,1)
4.9406564584124654e-324
>>> random.uniform(0, numpy.nextafter(0,1))
0.0
>>> random.uniform(0, numpy.nextafter(0,1))
0.0
>>> random.uniform(0, numpy.nextafter(0,1))
4.9406564584124654e-324

[我认为可能有更好的方法来解决这个问题。]

【讨论】:

  • 为什么不是numpy.nextafter(1, 0) == (1-sys.float_info.epsilon),是因为float的密度会根据大小而变化?
  • @wim:是的。 1+epsilon/2 = 1,但 1-eps/2 = nextafter(1,0)。
【解决方案2】:

Python 的sys 提供了一个带有epsilon 属性的float_info 结构体,定义为

1 与大于 1 的可表示为浮点数的最小值之间的差

所以我想像

def clip(num):
    if(num >= 1):
        return 1 - sys.float_info.epsilon
    return num

应该可以解决问题。虽然这通常很糟糕,并且可能有很多理由让您永远不要尝试这样做。

编辑我刚刚观察到一个这样的原因 - 实施。虽然 CPython 可以满足您的期望,但我的第一个选择是 IronPython,doesn't(尽管这是一个错误)。请注意!

【讨论】:

  • 那么...有没有一般不坏的方法?
  • 这真的取决于你为什么需要你的函数在 [0, 1) 中。您想忽略 >= 1 的值吗?您想将这些值包含为 1 - eps 吗?谁在接受这些值,为什么那个人需要它们为 [0, 1)?您声明存在一个返回 [0, 1) 的库函数 u。然后你 f(u()) 这些数字并返回 [0, inf),但想返回 [0, 1) ...为什么?大概有一个 h(f(u)),也许我们应该关注 h。 :)
【解决方案3】:

在大多数实际情况下,您不需要无限小,您可以近似它。因此,对于您的示例,我将使用 0.9999999 而不是 1.0。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-04-23
    • 2016-01-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-19
    • 2023-01-08
    • 1970-01-01
    相关资源
    最近更新 更多