单位和数量的字符串表示法#
转换为字符串#
你可以控制 Quantity 和 UnitBase 使用 Python Format String Syntax (下面用 f-strings )
为. Quantity ,作为名称的格式说明符 Built-In Formats 应用于 Quantity 单位,如果可能的话,还可以将其转换为值。数值的格式说明符,如 .3f ,将应用于 Quantity 值,而不影响单位。最后,说明符如 ^20s 将应用于字符串,将应用于 Quantity 作为一个整体。的单位部分应用的格式说明符。 Quantity 也适用于 UnitBase 举个例子。
实例#
渲染 Quantity 或 UnitBase 字符串形式的对象:
>>> 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() 法就像 table.Column() 采用格式说明符或可调用格式来进行格式化,您还可以选择通过 formatter 具有类型或额外具有字典的参数,额外的好处是更灵活或更紧凑的LaTeX输出。它要依赖 numpy.array2string() 用于直接处理 formatter ,这将有效地覆盖由提供的科学和复杂符号的默认LaTeX格式 Quantity.to_string() 除非 formatter 只是一个格式说明符字符串,或者 None (by默认)::
>>> 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}}$'
>>> q.to_string(format="latex", formatter=".2e") # Specifying format_spec
'$1.25 \\times 10^{12} \\; \\mathrm{\\frac{pc}{Myr}}$'
>>> q.to_string(format="latex", formatter=lambda x: f"\\approx {float(x):.2e}") # Custom formatting (overwrites)
'$\\approx 1.25e+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 包括对解析和写入以下格式的支持:
"fits": This is the format defined in the Units section of the FITS Standard . 与“通用”字符串格式不同,它只接受或生成FITS标准中定义的单位。
"vounit": The Units in the VO 1.0 代表VO中单位的标准。同样,基于FITS语法,但支持的单元集合是不同的。
"cds": Standards for astronomical catalogues from Centre de Données astronomiques de Strasbourg: This is the standard used by Vizier tables ,以及可投票版本1.3和更早版本所使用的内容。
"ogip":存储单元的标准,由 Office of Guest Investigator Programs (OGIP) .
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⁻¹⁸ ───── s²
处理未获认可的单位#
由于许多野外文件的单位字符串不对应于任何给定标准, 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 可以采用三个值之一来控制此行为:
'raise':(默认)引发ValueError。
'warn':发出UnitParserWarning,并返回一个单位。
'silent':返回单位,而不会出现错误或发出警告。
单位类型返回时 parse_strict 是 'warn' 或 'silent' 取决于违反标准的严重程度在轻微违反标准的情况下, Unit 有时仍然可以解析该单元。警告消息(如果 parse_strict='warn' )然后将包含有关如何解释无效字符串的信息。如果出现较严重的违规行为, UnrecognizedUnit 而是返回实例。在这种情况下,特别是在拼写错误的单位的情况下,注册额外的单位别名可能会有所帮助 set_enabled_aliases() (e.g.,“Angstrom”代表“Angstrom”;如下所示),或通过定义新单位 def_unit() 和 add_enabled_units() ,
实例#
要设置设备别名,请传递 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.