【问题标题】:How to control the display precision of a NumPy float64 scalar?如何控制 NumPy float64 标量的显示精度?
【发布时间】:2021-03-23 23:58:44
【问题描述】:

我正在编写一份教学文档,该文档使用大量 Python 代码示例并包含生成的数字输出。我在 IPython 内部工作,很多示例都使用 NumPy。

想避免打印语句、显式格式或类型转换。它们使示例变得混乱,并有损于我试图解释的原则。

我知道的:

  • 在 IPython 中,我可以使用 %precision 来控制任何 float 结果的显示精度。

  • 我可以使用np.set_printoptions() 来控制元素的显示精度 NumPy 数组中。

我正在寻找的是一种控制 NumPy float64 标量的显示精度的方法,它不响应上述任何一个。这些由许多 NumPy 函数返回。

>>> x = some_function()
Out[2]: 0.123456789

>>> type(x)
Out[3]: numpy.float64

>>> %precision 2
Out[4]: '%.2f'

>>> x
Out[5]: 0.123456789

>>> float(x)  # that precision works for regular floats
Out[6]: 0.12

>>> np.set_printoptions(precision=2)

>>> x  # but doesn't work for the float64
Out[8]: 0.123456789

>>> np.r_[x]  # does work if it's in an array
Out[9]: array([0.12])

我想要的是

>>> # some formatting command
>>> x = some_function() # that returns a float64 = 0.123456789
Out[2]: 0.12

但我愿意接受:

  • 一种告诉 NumPy 默认给我float 标量的方法,而不是float64
  • 一种告诉 IPython 如何处理 float64 的方法,有点像我可以为自己的课程使用 repr_pretty 做的事情。

【问题讨论】:

  • x.item() 有帮助吗?
  • @hpaulj 是的,但不超过float(x),这可能更具描述性。但是.item() 可以添加到末尾,而不必包装表达式。

标签: numpy format ipython precision float64


【解决方案1】:

IPython 有格式化程序 (core/formatters.py),其中包含一个将类型映射到格式化方法的 dict。格式化程序中似乎有一些关于 NumPy 的知识,但对于 np.float64 类型却没有。

有一个bunch of formatters,用于 HTML、LaTeX 等,但text/plain 是用于控制台的。

我们首先得到用于控制台文本输出的 IPython 格式化程序

plain = get_ipython().display_formatter.formatters['text/plain']

然后为float64 类型设置一个格式化程序,我们使用与float 相同的格式化程序,因为它已经知道%precision

plain.for_type(np.float64, plain.lookup_by_type(float))

现在

In [26]: a = float(1.23456789)

In [28]: b = np.float64(1.23456789)

In [29]: %precision 3
Out[29]: '%.3f'

In [30]: a
Out[30]: 1.235

In [31]: b
Out[31]: 1.235

在实现中我还发现%precision 使用合适的格式字符串调用np.set_printoptions()。我不知道它是这样做的,如果用户已经设置了它,可能会出现问题。按照上面的例子

In [32]: c = np.r_[a, a, a]

In [33]: c
Out[33]: array([1.235, 1.235, 1.235])

我们看到它对数组元素做了正确的事情。

我可以在我自己的代码中显式地执行此格式化程序初始化,但更好的解决方法可能是修改 IPython code/formatters.py 第 677 行

    @default('type_printers')
    def _type_printers_default(self):
        d = pretty._type_pprinters.copy()
        d[float] = lambda obj,p,cycle: p.text(self.float_format%obj)
        # suggested "fix"
        if 'numpy' in sys.modules:
            d[numpy.float64] = lambda obj,p,cycle: p.text(self.float_format%obj)
        # end suggested fix
        return d

如果包含NumPy,也可以在此处处理np.float64。很高兴收到对此的反馈,如果我有勇气,我可能会提交 PR。

【讨论】:

    猜你喜欢
    • 2019-07-28
    • 2017-11-15
    • 1970-01-01
    • 1970-01-01
    • 2014-04-15
    • 2021-08-16
    • 1970-01-01
    • 2014-11-13
    • 2018-10-25
    相关资源
    最近更新 更多