【问题标题】:Numpy array tolist() problem with floating-point values浮点值的numpy数组tolist()问题
【发布时间】:2021-12-17 19:02:26
【问题描述】:

我有一个 Numpy 数组,它是通过将 Numpy 数组与浮点数相乘而获得的。

a = np.array([3, 5, 7, 9]) * 0.1

得到的数字是精确的,没有任何四舍五入。

>>> a
array([0.3 0.5 0.7 0.9])

但是,如果我将数组转换为带有 a.tolist() 的列表,则列表中会出现 0.30000000000000004 之类的条目,而不是 0.3

>>> a.tolist()
[0.30000000000000004, 0.5, 0.7000000000000001, 0.9]

我的问题是,我该如何避免这种情况,如果有人出于纯粹的兴趣知道为什么会发生这种情况。非常感谢您的帮助。

【问题讨论】:

  • 从 Numpy 文档的摘录中可能会了解它发生的原因:Data items are converted to the nearest compatible builtin Python type。你试过用 list() 代替吗?
  • @BedirYilmaz list(a) 也给出了我尝试过的混乱浮动结果。
  • 这是一个显示问题,而不是转换问题。
  • 正如 hpaulj 所说,这与 tolist 无关,您可以通过 with np.printoptions(precision=20): print(np.array([3, 5, 7, 9]) * 0.1) 进行检查

标签: numpy tolist


【解决方案1】:

这个问题通常与浮点有关(在 Python 控制台中执行 3 * .1)。在您的情况下,您可以简单地除以 10 而不是 0.1 的倍数。

a = np.array([3, 5, 7, 9]) / 10

另见:Floating Point Error Mitigation Decimal Module

【讨论】:

    【解决方案2】:

    这不是 Numpy 的问题。相反,这是 Python 和其他语言中众所周知的 problem with floating-point values

    你可以在 Python 终端试试这个。

    >>> 3 * 0.1
    0.30000000000000004
    

    但是,这里有区别。

    这里的区别在于 Numpy 和 Python 如何表示这些值。

    当你打印一个 Numpy 数组时,它会将数组传递给 np.array_repr 并返回数组的字符串表示形式。

    注意参数precision。默认设置为numpy.get_printoptions()['precision']8

    >>> np.get_printoptions()['precision']
    8
    

    这比0.30000000000000004 的精度17 要早。因此,我们看到的结果被四舍五入为0.3

    让我们用precision 设置尝试更多。

    >>> a = np.array([3, 5, 7, 9]) * 0.1
    

    precision=17

    >>> print(np.array_repr(a, precision=17))
    array([0.30000000000000004, 0.5, 0.7000000000000001, 0.9])
    

    precision=16

    >>> print(np.array_repr(a, precision=16))
    arrayarray([0.3, 0.5, 0.7000000000000001, 0.9])
    

    precision=15

    >>> print(np.array_repr(a, precision=15))
    array([0.3, 0.5, 0.7, 0.9])
    

    将 Numpy 数组转换为列表时,由于列表在表示值时不具备精度特性,因此列表中的浮点值按原样显示。

    如果您希望值在转换为列表时看起来相同,请至少将它们四舍五入到小数点后八位。

    >>> print(list(np.round(a, 8)))
    [0.3, 0.5, 0.7, 0.9]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-06-27
      • 2011-03-04
      • 1970-01-01
      • 2021-03-29
      • 2021-11-21
      • 2020-03-15
      • 1970-01-01
      相关资源
      最近更新 更多