数量#

这个 Quantity 对象表示一个值,该值具有与该数字相关的单位。

创建数量实例#

Quantity 对象通常是通过与相乘来创建的 Unit 物体。

实例#

创建一个 Quantity 代表15 m/s:

>>> import astropy.units as u
>>> 15 * u.m / u.s  
<Quantity 15. m / s>

这如预期的那样扩展到除以一个单位,或使用 numpy 数组或 Python sequences

>>> 1.25 / u.s
<Quantity 1.25 1 / s>
>>> [1, 2, 3] * u.m  
<Quantity [1., 2., 3.] m>
>>> import numpy as np
>>> np.array([1, 2, 3]) * u.m  
<Quantity [1., 2., 3.] m>

也可以使用 Quantity 构造函数,通过指定值和单位:

>>> u.Quantity(15, u.m / u.s)  
<Quantity 15. m / s>

构造函数提供了更多的选项。特别是,它允许您合并 Quantity 对象(只要它们的所有单元都是等效的),以及解析简单字符串(这可能有助于,例如,解析配置文件等):

>>> qlst = [60 * u.s, 1 * u.min]
>>> u.Quantity(qlst, u.minute)  
<Quantity [1.,  1.] min>
>>> u.Quantity('15 m/s')  
<Quantity 15. m / s>

可以通过访问当前单位和值 unitvalue 属性:

>>> q = 2.5 * u.m / u.s
>>> q.unit
Unit("m / s")
>>> q.value
2.5

备注

Quantity 默认情况下,对象转换为浮点。此外,传入的任何数据都会被复制,这对于大型数组来说可能不是最优的。正如所讨论的那样 further below ,您可以改为获取一个 view 通过路过 copy=FalseQuantity 或通过使用 << 接线员。

转换为不同单位#

Quantity 对象可以使用 to() 方法。

实例#

转换 Quantity 不同单位的对象:

>>> q = 2.3 * u.m / u.s
>>> q.to(u.km / u.h)  
<Quantity 8.28 km / h>

为方便起见, sicgs 属性可用于将 Quantity 到基地 SICGS 单位:

>>> q = 2.4 * u.m / u.s
>>> q.si  
<Quantity 2.4 m / s>
>>> q.cgs  
<Quantity 240. cm / s>

如果您想在不同的单位中显示数量的值,可以使用 to_value() 作为快捷方式:

>>> q = 2.5 * u.m
>>> q.to_value(u.cm)
250.0

备注

你可以把它的价值 cm 还可以通过使用 q.to(u.cm).value 。区别在于, to_value() 如果单位已经是正确的单位,则不进行复制,而是返回一个 view 数据(就像您已经完成的一样 q.value )。相比之下, to() 始终返回副本(这也意味着在不需要转换的情况下速度较慢)。正如所讨论的那样 further below ,您可以通过使用 << 接线员。

比较数量#

平等性 Quantity 对象的最佳测试方法是使用 allclose()isclose() 函数,这些函数是 numpy 具有相同名称的函数::

>>> u.allclose([1, 2] * u.m, [100, 200] * u.cm)
True
>>> u.isclose([1, 2] * u.m, [100, 20] * u.cm)
array([ True, False])

对.的使用 Python comparison operators 还支持::

>>> 1*u.m < 50*u.cm
False

绘制数量#

Quantity 可以使用以下工具方便地绘制对象 Matplotlib -请参见 绘制数量 了解更多详细信息。

算术#

加减法#

加减法 Quantity 如果对象的单位相等,则支持这些对象。

实例#

当单位相等时,生成的对象具有相同的单位:

>>> 11 * u.s + 30 * u.s  
<Quantity 41. s>
>>> 30 * u.s - 11 * u.s  
<Quantity 19. s>

如果单位相等,但不相等(例如公里和米),则结果对象 在左边有对象的单位

>>> 1100.1 * u.m + 13.5 * u.km
<Quantity 14600.1 m>
>>> 13.5 * u.km + 1100.1 * u.m  
<Quantity 14.6001 km>
>>> 1100.1 * u.m - 13.5 * u.km
<Quantity -12399.9 m>
>>> 13.5 * u.km - 1100.1 * u.m  
<Quantity 12.3999 km>

之间不支持加减法 Quantity 对象和基本数值类型,但无量纲数量除外(请参见 Dimensionless Quantities )或特殊的值,如0和无穷大::

>>> 13.5 * u.km + 19.412  
Traceback (most recent call last):
  ...
UnitConversionError: Can only apply 'add' function to dimensionless
quantities when other argument is not a quantity (unless the
latter is all zero/infinity/nan)

乘除#

支持乘法和除法 Quantity 具有任意单位和数字类型的对象。对于具有等效单位的对象之间的这些操作 结果对象具有复合单位 .

实例#

执行这些操作 Quantity 物体:

>>> 1.1 * u.m * 140.3 * u.cm  
<Quantity 154.33 cm m>
>>> 140.3 * u.cm * 1.1 * u.m  
<Quantity 154.33 cm m>
>>> 1. * u.m / (20. * u.cm)  
<Quantity 0.05 m / cm>
>>> 20. * u.cm / (1. * u.m)  
<Quantity 20. cm / m>

对于乘法,可以通过使用 to() 方法:

>>> (1.1 * u.m * 140.3 * u.cm).to(u.m**2)  
<Quantity 1.5433 m2>
>>> (1.1 * u.m * 140.3 * u.cm).to(u.cm**2)  
<Quantity 15433. cm2>

对于分割,如果单位相等,则可能需要通过减少单位使生成的对象无量纲。为此,请使用 decompose() 方法:

>>> (20. * u.cm / (1. * u.m)).decompose()  
<Quantity 0.2>

此方法也适用于更复杂的运算:

>>> 15. * u.kg * 32. * u.cm * 15 * u.m / (11. * u.s * 1914.15 * u.ms)  
<Quantity 0.34195097 cm kg m / (ms s)>
>>> (15. * u.kg * 32. * u.cm * 15 * u.m / (11. * u.s * 1914.15 * u.ms)).decompose()  
<Quantity 3.41950973 m2 kg / s2>

NumPy函数#

Quantity 对象实际上已满 numpy 数组(的 Quantity 类继承自并扩展 numpy.ndarray )我们努力确保 numpy 函数的行为与量有关:

>>> q = np.array([1., 2., 3., 4.]) * u.m / u.s
>>> np.mean(q)
<Quantity 2.5 m / s>
>>> np.std(q)  
<Quantity 1.11803399 m / s>

这包括只接受特定单位的函数,例如角度:

>>> q = 30. * u.deg
>>> np.sin(q)  
<Quantity 0.5>

Dimensionless Quantities **

>>> from astropy.constants import h, k_B
>>> nu = 3 * u.GHz
>>> T = 30 * u.K
>>> np.exp(-h * nu / (k_B * T))  
<Quantity 0.99521225>

备注

支持来自其他包的函数,例如 SciPy ,是更不完整的(欢迎为改善这一点作出贡献!)。

无量纲量#

无量纲量具有这样的特征:如果将它们添加到或减去Python标量或无量纲 ndarray ,或者如果它们被传递给 numpy 函数接受无量纲数量,简化了单位,使数量是无量纲和无标度的。例如:

>>> 1. + 1. * u.m / u.km  
<Quantity 1.001>

不同于:

>>> 1. + (1. * u.m / u.km).value
2.0

在后一种情况下,结果是 2.0 因为 (1. * u.m / u.km) 默认情况下不可缩放:

>>> q = (1. * u.m / u.km)
>>> q.unit
Unit("m / km")
>>> q.unit.decompose()
Unit(dimensionless with a scale of 0.001)

但是,当与不是 Quantity ,将单元自动分解为无标度,得到了预期的结果。

当将无量纲量传递给采用无量纲量的函数时,也会发生这种情况:

>>> nu = 3 * u.GHz
>>> T = 30 * u.K
>>> np.exp(- h * nu / (k_B * T))  
<Quantity 0.99521225>

结果与指定不同数量的单位无关:

>>> nu = 3.e9 * u.Hz
>>> T = 30 * u.K
>>> np.exp(- h * nu / (k_B * T))  
<Quantity 0.99521225>

转换为纯Python标量#

转换 Quantity 对象不适用于无量纲数量:

>>> float(3. * u.m)
Traceback (most recent call last):
  ...
TypeError: only dimensionless scalar quantities can be converted
to Python scalars

只有无量纲值才能转换为普通的Python标量:

>>> float(3. * u.m / (4. * u.m))
0.75
>>> float(3. * u.km / (4. * u.m))
750.0
>>> int(6. * u.km / (2. * u.m))
3000

接受数量的函数#

如果函数接受 Quantity 作为一个论点,最好检查一下提供的 Quantity 属于预期中的 物理类型 。这可以使用 decorator quantity_input()

装饰符不会转换输入 Quantity 到所需的单位,例如下例中的角秒对度,它只检查这样的转换是可能的,从而验证 Quantity 参数可以在计算中使用。

关键字参数 quantity_input() 指定应验证哪些参数以及它们应与哪个单元兼容。

实例#

要验证是否存在 Quantity 参数可以在计算中使用:

>>> @u.quantity_input(myarg=u.deg)
... def myfunction(myarg):
...     return myarg.unit

>>> myfunction(100*u.arcsec)
Unit("arcsec")
>>> myfunction(2*u.m)  
Traceback (most recent call last):
...
UnitsError: Argument 'myarg' to function 'myfunction' must be in units
convertible to 'deg'.

也可以改为指定 physical type 所需单位的:

>>> @u.quantity_input(myarg='angle')
... def myfunction(myarg):
...     return myarg.unit

>>> myfunction(100*u.arcsec)
Unit("arcsec")

可选地, None 还支持关键字参数;对于这种情况,仅当值不是 None 是传递的::

>>> @u.quantity_input(a='length', b='angle')
... def myfunction(a, b=None):
...     return a, b

>>> myfunction(1.*u.km)  
(<Quantity 1. km>, None)
>>> myfunction(1.*u.km, 1*u.deg)  
(<Quantity 1. km>, <Quantity 1. deg>)

或者,您可以使用 annotations syntax 来提供这些单位。虽然可以使用原始单位或字符串,但首选的方法是使用支持单位数量的注释语法。

Quantity[unit or "string", metadata, ...]

>>> @u.quantity_input
... def myfunction(myarg: u.Quantity[u.arcsec]):
...     return myarg.unit
>>>
>>> myfunction(100*u.arcsec)
Unit("arcsec")

您还可以为非单元期望参数中的不同类型添加注释:

>>> @u.quantity_input
... def myfunction(myarg: u.Quantity[u.arcsec], nice_string: str):
...     return myarg.unit, nice_string
>>> myfunction(100*u.arcsec, "a nice string")
(Unit("arcsec"), 'a nice string')

例如,可以将输出指定为具有带有函数注释的所需单位

>>> @u.quantity_input
... def myfunction(myarg: u.Quantity[u.arcsec]) -> u.deg:
...     return myarg*1000
>>>
>>> myfunction(100*u.arcsec)  
<Quantity 27.77777778 deg>

这将检查函数的返回值是否与期望值一致,并使函数结果的显示更简洁。

指定有效等效单位的列表或 物理类型 应接受具有多个有效单位的输入的函数支持:

>>> @u.quantity_input(a=['length', 'speed'])
... def myfunction(a):
...     return a.unit
>>> myfunction(1.*u.km)
Unit("km")
>>> myfunction(1.*u.km/u.s)
Unit("km / s")

用单位表示向量#

Quantity 对象可以,如 numpy 数组通过指定特定维度来表示坐标或矩阵元素来表示向量或矩阵,但这意味着要仔细跟踪这些维度。对于向量 使用和设计坐标表示法 可以更方便,因为这样做允许您使用笛卡尔以外的表示法(如球面或圆柱面),以及简单的矢量算术。

创建和转换无副本的数量#

创建一个 Quantity 使用与单位相乘的方法,生成底层数据的副本。这可以通过传递来避免 copy=False 在初始值设定项中。

实例#

避免重复使用 copy=False ::

>>> a = np.arange(5.)
>>> q = u.Quantity(a, u.m, copy=False)
>>> q  
<Quantity [0., 1., 2., 3., 4.] m>
>>> np.may_share_memory(a, q)
True
>>> a[0] = -1.
>>> q  
<Quantity [-1.,  1.,  2.,  3.,  4.] m>

这在不更改其输入的函数中可能特别有用,同时确保如果用户传入 Quantity 然后,它将被转换为所需的单位。

作为快捷方式,您可以使用 << 操作员:

>>> q = a << u.m
>>> np.may_share_memory(a, q)
True
>>> q  
<Quantity [-1.,  1.,  2.,  3.,  4.] m>

运算符的工作方式与初始化相同 copy=False 如上所述:

>>> q << u.cm  
<Quantity [-100.,  100.,  200.,  300.,  400.] cm>

也可用于就地转换:

>>> q <<= u.cm
>>> q  
<Quantity [-100.,  100.,  200.,  300.,  400.] cm>
>>> a  
array([-100.,  100.,  200.,  300.,  400.])

这个 numpy.dtype 指数量#

Quantity 子类 numpy.ndarray 并类似地接受一个 dtype 争论。

>>> q = u.Quantity(1.0, dtype=np.float32)
>>> q.dtype
dtype('float32')

LIKE FOR numpy.ndarraydtype 不需要指定,在这种情况下,会检查数据以找到最佳 dtype 。为 numpy 这意味着整数仍然是整数,而 Quantity 相反,将整数向上强制转换为浮点数。

>>> v = np.array(1)
>>> np.issubdtype(v.dtype, np.integer)
True
>>> q = u.Quantity(1)
>>> np.issubdtype(q.dtype, np.integer)
False

Quantity 将整型提升为浮点型,因为它对 dtypenumpy -- numpy.inexactNone 。为 Quantity 使用相同的 dtype 作为检查对象 numpy ,使用 dtype=None

>>> q = u.Quantity(1, dtype=None)
>>> np.issubdtype(q.dtype, np.integer)
True

请注意 numpy.inexact 是一个已弃用的 dtype 论据 numpy.ndarrayQuantity 变化 numpy.inexactnumpy.float64 ,但不会更改已经是浮点或复数的数据。

QTable#

它可以使用 Quantity 对象在中作为列 astropy.table 。看见 数量和数量 了解更多详细信息。

子类量#

划分为子类 Quantity ,您通常按照子类化时的方式进行操作 numpy.ndarray (即,您通常需要覆盖 __new__() ,而不是 __init__() ,并使用 numpy.ndarray.__array_finalize__() 方法来更新属性)。有关详细信息,请参阅 NumPy documentation on subclassing 。要了解所涉及的内容,请查看 Quantity 本身,其中,例如, astropy.units.Quantity.__array_finalize__() 方法用于传递 unit ,位于 Angle ,其中字符串被解析为 astropy.coordinates.Angle.__new__() 方法和在 Longitude ,其中 astropy.coordinates.Longitude.__array_finalize__() 方法用于传递经度换行的角度。

另一个旨在由子类重写的方法,特定于 Quantity ,是 astropy.units.Quantity.__quantity_subclass__() 。方法的单位来决定返回哪种类型的子类。 Quantity 那是要被创造的。例如,它被用在 Angle 要返回一个 Quantity 如果计算返回角度单位以外的单位。这一点的实施是通过 SpecificTypeQuantity ,它更一般地允许用户构造 Quantity 具有仅对特定物理类型有用的方法的子类。