单位和数量的字符串表示法#

转换为字符串#

你可以控制 QuantityUnitBase 使用 Python Format String Syntax (下面用 f-strings

为. Quantity ,作为名称的格式说明符 Built-In Formats 应用于 Quantity 单位,如果可能的话,还可以将其转换为值。数值的格式说明符,如 .3f ,将应用于 Quantity 值,而不影响单位。最后,说明符如 ^20s 将应用于字符串,将应用于 Quantity 作为一个整体。的单位部分应用的格式说明符。 Quantity 也适用于 UnitBase 举个例子。

实例#

渲染 QuantityUnitBase 字符串形式的对象:

>>> from astropy import units as u
>>> q = 10.5 * u.km
>>> q
<Quantity  10.5 km>
>>> f"{q}"
'10.5 km'
>>> f"{q:latex}"
'$10.5 \\; \\mathrm{km}$'
>>> f"{q:+.3f}"
'+10.500 km'
>>> f"{q:^20}"
'        10.5         km'
>>> f"{q:^20s}"
'     10.5 km        '

若要分别格式化值和单位,可以访问 Quantity 格式字符串中的属性::

>>> q = 10.5 * u.km
>>> q
<Quantity  10.5 km>
>>> f"{q.value:.3f} in {q.unit}"
'10.500 in km'

这可能不适用于LaTeX字符串,在这种情况下,最好使用 Quantity.to_string() 方法:

>>> q = 1.2478e12 * u.pc/u.Myr
>>> f"{q:latex}"  # Might not have the number of digits we would like
'$1.2478 \\times 10^{12} \\; \\mathrm{\\frac{pc}{Myr}}$'
>>> f"{q.value:.3e} {q.unit:latex}"  # The value is not in LaTeX
'1.248e+12 $\\mathrm{\\frac{pc}{Myr}}$'
>>> q.to_string(format="latex", precision=4)  # Right number of LaTeX digits
'$1.248 \\times 10^{12} \\; \\mathrm{\\frac{pc}{Myr}}$'

因为 numpy.ndarray 不接受大多数格式说明符,使用诸如 .3f 在应用于 numpy.ndarray 或非标量 Quantity 。使用 numpy.array_str() 取而代之的是。例如:

>>> import numpy as np
>>> q = np.linspace(0,1,10) * u.m
>>> f"{np.array_str(q.value, precision=1)} {q.unit}"  
'[0.  0.1 0.2 0.3 0.4 0.6 0.7 0.8 0.9 1. ] m'

查看NumPy文档以获取更多示例 numpy.array_str() .

A UnitBase 的单位部分,或 Quantity ,还可以采用多种不同的样式进行格式化。默认情况下,使用的字符串格式是“通用”格式,该格式基于 FITS standard 表示单位的格式,但支持在 astropy.units 框架,包括用户定义的单位。格式说明符(和 UnitBase.to_string() )函数还使用可选参数来选择不同的格式::

>>> q = 10 * u.km
>>> f"{q:latex}"
'$10 \\; \\mathrm{km}$'
>>> fluxunit = u.erg / (u.cm ** 2 * u.s)
>>> f"{fluxunit}"
'erg / (s cm2)'
>>> print(f"{fluxunit:unicode}")
erg s⁻¹ cm⁻²
>>> f"{fluxunit:latex}"
'$\\mathrm{\\frac{erg}{s\\,cm^{2}}}$'
>>> f"{fluxunit:>20s}"
'       erg / (s cm2)'

这个 UnitBase.to_string() 方法是将单元格式化为字符串的另一种方法,并且是 format -风格用法::

>>> fluxunit = u.erg / (u.cm ** 2 * u.s)
>>> fluxunit.to_string('latex')
'$\\mathrm{\\frac{erg}{s\\,cm^{2}}}$'

从字符串转换#

也可以使用 Unit 班级:

>>> u.Unit("m")
Unit("m")
>>> u.Unit("erg / (s cm2)")
Unit("erg / (s cm2)")
>>> u.Unit("erg.s-1.cm-2", format="cds")
Unit("erg / (s cm2)")

还可以创建标量 Quantity 来自字符串::

>>> u.Quantity("3m/s")
<Quantity 3. m / s>

备注

从字符串转换需要使用针对单元语言的专用解析器,这会导致性能下降。它使用起来要快得多 UnitBase 对象直接(例如, unit = u.degree / u.minute )而不是通过字符串解析 (unit = u.Unit('deg/min') )。但是,如果您的单元定义来自FITS或VOTABLE等文件格式,则此解析器非常有用。

内置格式#

astropy.units 包括对解析和写入以下格式的支持:

astropy.units 还可以写入但不能读取以下格式的单位:

  • "latex" :使用LaTeX数学语法将单位写出 IAU Style Manual 关于单元陈述的建议。打印中的单位时会自动使用此格式 IPython 笔记本::

    >>> f"{fluxunit:latex}"
    '$\\mathrm{\\frac{erg}{s\\,cm^{2}}}$'
    

    它将呈现为

    \[\数学{\frac{erg}{s\,cm^{2}}}\]
  • "latex_inline" :使用LaTeX数学语法,使用 IAU Style Manual 根据某些期刊的要求,使用负幂而不是分数来表示单位(例如。, Apj and AJ ). 最适合与文本内联的单位表示:

    >>> fluxunit.to_string('latex_inline')
    '$\\mathrm{erg\\,s^{-1}\\,cm^{-2}}$'
    

    它将呈现为

    \[\数学{erg\、s^{-1}\、cm^{2}}\]
  • "console" :写入用于在文本控制台中显示的单位的表示形式::

    >>> print(fluxunit.to_string('console'))
     erg s^-1 cm^-2
    

    也可以在单行上使用分数,

    >>> print(fluxunit.to_string('console', fraction='inline'))
    erg / (s cm^2)
    

    或使用多线表示法:

    >>> print(fluxunit.to_string('console', fraction='multiline'))
     erg
    ------
    s cm^2
    
  • "unicode" 一样 "console" ,除非使用Unicode字符:

    >>> print(u.Ry.decompose().to_string('unicode'))  
    2.1798724×10⁻¹⁸ m² kg s⁻²
    >>> print(u.Ry.decompose().to_string('unicode', fraction=True))  
    2.1798724×10⁻¹⁸ m² kg / s²
    >>> print(u.Ry.decompose().to_string('unicode', fraction='multiline'))  
                    m² kg
    2.1798724×10⁻¹⁸ ─────
    
    

处理未获认可的单位#

由于在野外发现的许多文件具有不对应于任何给定标准的单位字符串, astropy.units 还具有存储和传递未解析的单元字符串的一致方式。此外,它还提供了用于将非标准、遗留或拼写错误的单元字符串转换为其标准化形式的工具,从而防止这些单元字符串的进一步传播。

默认情况下,传递无法识别的单位字符串会引发异常::

>>> # The FITS standard uses 'angstrom', not 'Angstroem'
>>> u.Unit("Angstroem", format="fits")
Traceback (most recent call last):
  ...
ValueError: 'Angstroem' did not parse as fits unit: At col 0, Unit
'Angstroem' not supported by the FITS standard. Did you mean Angstrom
or angstrom? If this is meant to be a custom unit, define it with
'u.def_unit'. To have it recognized inside a file reader or other
code, enable it with 'u.add_enabled_units'. For details, see
https://docs.astropy.org/en/latest/units/combining_and_defining.html

然而, Unit 构造函数具有关键字参数 parse_strict 可以采用以下三个值之一来控制此行为:

通过为拼写错误的单元添加额外的单元别名 set_enabled_aliases() (例如,‘Angstrom’代表‘Angstrom’;如下所示),或通过定义新单位 def_unit()add_enabled_units() ,我们可以使用 parse_strict='raise' 快速发现所用单位的问题,同时还能够读取单位使用可能不太标准的较旧数据集。

实例#

要设置设备别名,请传递 set_enabled_aliases() 一个 dict 将拼写错误的字符串映射到占星体单位。以下代码片段显示了如何设置Angstroem->Angstrom::

>>> u.set_enabled_aliases({"Angstroem": u.Angstrom})
<astropy.units.core._UnitContext object at 0x...>
>>> u.Unit("Angstroem")
Unit("Angstrom")
>>> u.Unit("Angstroem") == u.Angstrom
True

您还可以一次设置多个别名或添加到现有别名:

>>> u.set_enabled_aliases({"Angstroem": u.Angstrom, "Angstroms": u.Angstrom})
<astropy.units.core._UnitContext object at 0x...>
>>> u.add_enabled_aliases({"angstroem": u.Angstrom})
<astropy.units.core._UnitContext object at 0x...>
>>> u.Unit("Angstroem") == u.Unit("Angstroms") == u.Unit("angstroem") == u.Angstrom
True

可以通过传递空词典::来重置别名

>>> u.set_enabled_aliases({})
<astropy.units.core._UnitContext object at 0x...>

你可以两者都用 set_enabled_aliases()add_enabled_aliases() 作为一名 context manager ,限制使用特定别名的位置::

>>> with u.add_enabled_aliases({"Angstroem": u.Angstrom}):
...     print(u.Unit("Angstroem") == u.Angstrom)
True
>>> u.Unit("Angstroem") == u.Angstrom
Traceback (most recent call last):
  ...
ValueError: 'Angstroem' did not parse as unit: At col 0, Angstroem is not
a valid unit. Did you mean Angstrom, angstrom, mAngstrom or mangstrom? If
this is meant to be a custom unit, define it with 'u.def_unit'. To have it
recognized inside a file reader or other code, enable it with
'u.add_enabled_units'. For details, see
https://docs.astropy.org/en/latest/units/combining_and_defining.html

传递无法识别的单位字符串:

>>> x = u.Unit("Angstroem", format="fits", parse_strict="warn")  
UnitsWarning: 'Angstroem' did not parse as fits unit: At col 0, Unit
'Angstroem' not supported by the FITS standard. Did you mean Angstrom or
angstrom? If this is meant to be a custom unit, define it with 'u.def_unit'.
To have it recognized inside a file reader or other code, enable it with
'u.add_enabled_units'. For details, see
https://docs.astropy.org/en/latest/units/combining_and_defining.html

这个 UnrecognizedUnit 对象会记住创建它时使用的原始字符串,因此可以将其写回,但对它执行的任何有意义的操作(例如转换到另一个单元或与其他单元组合)都将失败。

>>> x.to_string()
'Angstroem'
>>> x.to(u.km)
Traceback (most recent call last):
  ...
ValueError: The unit 'Angstroem' is unrecognized.  It can not be
converted to other units.
>>> x / u.m
Traceback (most recent call last):
  ...
ValueError: The unit 'Angstroem' is unrecognized, so all arithmetic
operations with it are invalid.