【问题标题】:Strange behavior when casting numpy.float64 to float将 numpy.float64 转换为浮动时的奇怪行为
【发布时间】:2013-10-22 07:20:14
【问题描述】:

numpy.arange 生成的对象出现了最奇怪的行为:

for i in numpy.arange(xo, xn+h, h):
    xs.append(float(i))

在这种情况下,xo=1xn=4h=0.1

现在,我希望 xs[-1] 完全等于 4.0 == float(4)。但是,我得到以下信息:

>>> foo = xs[-1]
>>> foo == float(4)
False
>>> float(foo) == float(4)
False
>>> foo
4.0
>>> type(foo)
<type 'float'>
>>> int(sympy.ceiling(4.0)), int(sympy.ceiling(foo))
4 5

这里到底发生了什么?

print type(i) 放在for 循环中会打印出&lt;type 'numpy.float64'&gt;。在float(i) 选角期间可能发生了什么?使用numpy.asscalar 不会改变任何东西。

使用math.ceil(foo) 而不是sympy.ceiling(foo) 会产生同样的问题(这是我真正需要工作的部分)。

【问题讨论】:

  • numpy.float64 vs sympy.float?如果你使用 sympy,我猜你可能会遇到类似的问题?
  • @usethedeathstar 我使用内置的float() 进行投射。 Sympy 只用在上面控制台 I/O 的最后一行。而且,正如我所说,使用 math.ceil 而不是 sympy.ceiling 返回相同。
  • 你应该避免 np.arange 使用浮点数。而是使用np.linspace

标签: python numpy casting floating-point sympy


【解决方案1】:
In [10]: for i in numpy.arange(xo, xn+h, h):
        xs.append(float(i))
....:     

In [11]: xs
Out[11]: 
[1.0,
1.1,
1.2000000000000002,
1.3000000000000003,
1.4000000000000004,
1.5000000000000004,
1.6000000000000005,
1.7000000000000006,
1.8000000000000007,
1.9000000000000008,
2.000000000000001,
2.100000000000001,
2.200000000000001,
2.300000000000001,
2.4000000000000012,
2.5000000000000013,
2.6000000000000014,
2.7000000000000015,
2.8000000000000016,
2.9000000000000017,
3.0000000000000018,
3.100000000000002,
3.200000000000002,
3.300000000000002,
3.400000000000002,
3.500000000000002,
3.6000000000000023,
3.7000000000000024,
3.8000000000000025,
3.9000000000000026,
4.000000000000003]

这就是为什么你没有得到想要的结果,由于浮点精度,它不能给你的测试 True。这也解释了为什么如果你在它上面做一个像天花板这样的圆形操作,你会得到五个而不是四个。

编辑: 要检查 x 和 y 是否相同(在一定误差范围内),您可以执行以下操作,但我认为(应该)python 中已经有一些东西可以为您执行此操作

def isnear(x,y, precision = 1e-5):
    return abs(x-y)<precision

编辑2: 或者如 ali_m 所说:

numpy.allclose(x, y, atol = 1e-5)

【讨论】:

  • 好吧,让我感到奇怪的是,在使用 float(xs[-1]) 进行投射后,您只会得到 4.0 作为输出。那么,最好的方法是让它正确吗? round(i)?
  • @Alex 我认为在 python 中实现了一些东西来检查 x 是否接近 y,如果你自己实现它,你可以尝试 abs(x-y)
  • @Alex:不要测试f1 == f2,其中f1f2都是浮点数,通常最好测试abs(f1-f2) &lt; eps,其中eps是一个适当小的大小的数字。在这种情况下,eps 的值介于 0.01 和 0.0000000000001 之间就可以了。
  • @Alex 这是否回答了您的问题,还是您需要更多信息?
  • 为方便起见,您也可以使用np.allclose(x, y, atol=eps)
【解决方案2】:

这并不奇怪——这正是浮点运算的工作方式,因为它不能准确地表示大多数值。如果您在浮点数中重复计算(arange() 这里是将 0.1 加到 1,然后再将 0.1 加到该总和上 29 次)并且如果您正在处理的数字不能用浮点数精确表示,您将不会得到计算结束时的准确答案。最好的文章是What Every Computer Scientist Should Know About Floating-Point Arithmetic

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-07
    • 2021-04-01
    • 2020-08-24
    • 2010-10-24
    • 1970-01-01
    相关资源
    最近更新 更多