【问题标题】:Rounding in numpy?在numpy中四舍五入?
【发布时间】:2017-03-15 15:15:12
【问题描述】:

我对 python pandas 和 numpy 有奇怪的问题。

>>> np.float64(1) * np.float64(85000) * np.float64(7.543709)
641215.26500000001

>>> round( np.float64(1) * np.float64(85000) * np.float64(7.543709), 2 )
641215.26000000001

>>> np.round( np.float64(1) * np.float64(85000) * np.float64(7.543709), 2 )
641215.26000000001

如何四舍五入得到正确的结果641215.27?

【问题讨论】:

  • 简单地说,NumPy 的round 函数不会尝试进行正确的舍入。 round 实现有利于速度而不是不惜一切代价的准确性,因此有很多极端情况(例如这个)接近到中间值(但不一定是精确的中间值)最终以错误的方式四舍五入。

标签: python pandas numpy rounding


【解决方案1】:

Numpy 的 round 方法偏爱偶数,看一下 numpy 源代码的删减:

def round_(a, decimals=0, out=None):
    return around(a, decimals=decimals, out=out)

def around(a, decimals=0, out=None):
    """
    Evenly round to the given number of decimals.

    Notes
    -----
    For values exactly halfway between rounded decimal values, NumPy
    rounds to the nearest even value. Thus 1.5 and 2.5 round to 2.0,
    -0.5 and 0.5 round to 0.0, etc. Results may also be surprising due
    to the inexact representation of decimal fractions in the IEEE
    floating point standard [1]_ and errors introduced when scaling
    by powers of ten.

    Examples
    --------
    >>> np.around([0.37, 1.64])
    array([ 0.,  2.])
    >>> np.around([0.37, 1.64], decimals=1)
    array([ 0.4,  1.6])
    >>> np.around([.5, 1.5, 2.5, 3.5, 4.5]) # rounds to nearest even value
    array([ 0.,  2.,  2.,  4.,  4.])
    >>> np.around([1,2,3,11], decimals=1) # ndarray of ints is returned
    array([ 1,  2,  3, 11])
    >>> np.around([1,2,3,11], decimals=-1)
    array([ 0,  0,  0, 10])

    """

示例:

如果你需要打印字符串,你可以格式化它给你正确的答案:

import numpy as np

num = np.float64(1) * np.float64(85000) * np.float64(7.543709)
print(num)
print(float("{0:.2f}".format(num)))
print(np.round(num, 2))
print()

num += 0.02
print(num)
print(float("{0:.2f}".format(num)))
print(np.round(num, 2))

给你

641215.265
641215.27
641215.26

641215.285
641215.29
641215.28

【讨论】:

  • 哇,这太令人惊讶了。好答案!我认为问题是存在像.49999 这样的基础值,显示为.50000,但事实并非如此。
  • @JohnE:是的,这应该是四舍五入,即使是在平局的情况下。这是与此处相关的文档字符串的“按十次方缩放时引入的错误”部分。
  • @MarkDickinson 好的,谢谢。我想简而言之,这只是一个示例,对于浮点数,您将.5 之类的数字视为大约为.5 并且可以上升或下降,如果您不喜欢这样,那么您不应该使用浮点数! ;-)
【解决方案2】:

是的,但在使用数据框时不能使用 round( float(num), 2 ):

例如:df.first * df.second * df.third 在这种情况下如何四舍五入? 你不能发float(dt.first)?

这是一种解决方案:df.first.apply(lambda x: round(float(x), 2)) 不过我觉得不快……

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-08-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-12
    • 2019-04-11
    • 1970-01-01
    相关资源
    最近更新 更多