【问题标题】:pandas rounding, is this a bug?熊猫四舍五入,这是一个错误吗?
【发布时间】:2016-05-17 15:52:52
【问题描述】:

这是一个错误吗?当我四舍五入时,它实际上返回不同的结果。

import pandas as pd
pd.set_option('precision', 10)

pd.DataFrame([[1.446450001],[1.44645]]).round(4)

结果

    0
0   1.4465
1   1.4464

【问题讨论】:

  • 不是错误。 1.44645 可能会以二进制形式存储为向下舍入的内容。
  • @piRSquared 我该如何解决这个问题?
  • @piRSquared 不,这是错误的。这是关于四舍五入的策略
  • @MaxNoe 啊!谢谢,我正在读这篇文章。

标签: python pandas rounding


【解决方案1】:

这不是一个错误 - 而是一个未记录的怪癖。

DataFrame.round 在底层使用 numpy.around,其中:

对于恰好介于四舍五入的十进制值之间的值,Numpy 会四舍五入到最接近的偶数值。因此 1.5 和 2.5 舍入为 2.0,-0.5 和 0.5 舍入为 0.0,等等。

http://docs.scipy.org/doc/numpy-1.10.1/reference/generated/numpy.around.html

更多阅读@维基百科:https://en.wikipedia.org/wiki/Rounding#Round_half_to_even

【讨论】:

【解决方案2】:

有两种不同的舍入策略

  • 像您可能在学校学过的第一轮,恰好间隔一半的值(以 5 结尾)向上四舍五入

  • 第二轮到下一个偶数

第一种策略有副作用,即您的平均值具有正偏差,因为中心总是调得更高。这由第二种策略解决,该策略任意决定舍入到下一个偶数值。

Pandas 选择使用numpy.around,它实现了第二种策略。

【讨论】:

    【解决方案3】:

    您可以使用以下函数在 pandas 或 python 中进行正常舍入:

    import numpy
    
    def round_normal(n, decimals):
        # multiply the decimal by 10 to the number of decimals you want to round to
        multiplicand = 10 ** decimals
    
        # add 0.5 so that taking the floor will get you the right number when you 
        # divide by the multiplicand
    
        # e.g. 3.0449 to 2.d.p -> 304.49 + 0.5 = 304.59 -> floor(304.59) / 100 = 3.04
        # e.g. 3.045 to 2.d.p -> 304.5 + 0.5 = 305 -> floor(305) / 100 = 3.05
        rounded_n = numpy.floor(n * multiplicand + 0.5) / multiplicand
        return rounded_n
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-08-16
      • 1970-01-01
      • 1970-01-01
      • 2018-09-08
      • 2023-01-14
      • 2023-03-30
      • 1970-01-01
      • 2018-12-20
      相关资源
      最近更新 更多