2

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

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

我知道的:

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

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

我正在寻找的是一种控制 NumPyfloat64标量的显示精度的方法,它不响应上述任何一个。这些由许多 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 如何处理 a 的方法float64,有点像我可以repr_pretty为自己的类做的事情。
4

1 回答 1

2

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

一堆格式化程序,用于 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])

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

我可以在我自己的代码中显式地执行此格式化程序初始化,但更好的修复可能是修改 IPythoncode/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

np.float64如果包括在内,也在这里处理NumPy。很高兴收到对此的反馈,如果我觉得勇敢,我可能会提交 PR。

于 2021-03-27T07:35:28.930 回答