数量#
这个 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>
>>> q = 2.5 * u.m / u.s
>>> q.unit
Unit("m / s")
>>> q.value
2.5
备注
Quantity
默认情况下,对象转换为浮点。此外,传入的任何数据都会被复制,这对于大型数组来说可能不是最优的。正如所讨论的那样 further below ,您可以改为获取一个 view 通过路过 copy=False
至 Quantity
或通过使用 <<
接线员。
转换为不同单位#
实例#
转换 Quantity
不同单位的对象:
>>> q = 2.3 * u.m / u.s
>>> q.to(u.km / u.h)
<Quantity 8.28 km / h>
为方便起见, si
和 cgs
属性可用于将 Quantity
到基地 SI 或 CGS 单位:
>>> 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>
>>> 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.ndarray
, dtype
不需要指定,在这种情况下,会检查数据以找到最佳 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
将整型提升为浮点型,因为它对 dtype
比 numpy
-- numpy.inexact
与 None
。为 Quantity
使用相同的 dtype
作为检查对象 numpy
,使用 dtype=None
。
>>> q = u.Quantity(1, dtype=None)
>>> np.issubdtype(q.dtype, np.integer)
True
请注意 numpy.inexact
是一个已弃用的 dtype
论据 numpy.ndarray
。 Quantity
变化 numpy.inexact
至 numpy.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
具有仅对特定物理类型有用的方法的子类。