数量¶
这个 Quantity
对象表示一个值,该值具有与该数字相关的单位。
创建数量实例¶
Quantity
对象通常是通过与相乘来创建的 Unit
物体。
实例¶
创建一个 Quantity
代表15 m/s:
>>> import astropy.units as u
>>> 15 * u.m / u.s
<Quantity 15. m / s>
这可以按单位进行除法,或者使用 numpy
数组或Python序列:
>>> 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
对象可以进行如下比较:
>>> from astropy import units as u
>>> u.allclose([1, 2] * u.m, [100, 200] * u.cm)
True
>>> u.isclose([1, 2] * u.m, [100, 20] * u.cm)
array([ True, False])
算术¶
加减法¶
加减法 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
对象和基本数字类型:
>>> 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)
无量纲数量除外(参见 Dimensionless Quantities )
乘除¶
支持乘法和除法 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 kg m2 / 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>
见 Dimensionless Quantities 详情请参见下文。
备注
用 numpy
版本早于1.17,许多非算术函数都有 known issues ,或者忽略单元(例如。, np.dot
)或者没有正确初始化(例如。, np.hstack
). 这会传播到更复杂的函数,例如 np.linalg.norm
.
支持其他包中的函数,例如 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
对象,并且这些单位与所需的单位或物理类型兼容。
decorator不会将输入量转换为所需的单位,例如在下面的示例中,它只是检查这种转换是否可行,从而验证 Quantity
参数可用于计算。
装饰工 quantity_input
接受关键字参数,以指定应验证哪些参数以及它们与哪个单元兼容。
实例¶
验证 Quantity
参数可用于计算:
>>> @u.quantity_input(myarg=u.deg)
... def myfunction(myarg):
... return myarg.unit
>>> myfunction(100*u.arcsec)
Unit("arcsec")
也可以指定所需单元的物理类型:
>>> @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>)
或者,可以使用注释语法提供单位:
>>> @u.quantity_input
... def myfunction(myarg: u.arcsec):
... return myarg.unit
>>> myfunction(100*u.arcsec)
Unit("arcsec")
您还可以为非单元期望参数中的不同类型添加注释:
>>> @u.quantity_input
... def myfunction(myarg: 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.arcsec) -> u.deg:
... return myarg*1000
>>> myfunction(100*u.arcsec)
<Quantity 27.77777778 deg>
这将检查函数的返回值是否与期望值一致,并使函数结果的显示更简洁。
decorator还支持为应接受多个有效单元的输入的函数指定有效等效单元或物理类型的列表:
>>> @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.])
子类量¶
子类 Quantity
,通常会像子类化时那样继续 ndarray
(即,您通常需要覆盖 __new__
而不是 __init__
,并使用 numpy.ndarray.__array_finalize__
方法更新属性)。有关详细信息,请参见 NumPy documentation on subclassing . 要想了解其中的含义,请看一看 Quantity
它本身,例如 astropy.units.Quantity.__array_finalize__
方法传递 unit
,在 Angle
,其中字符串在 astropy.coordinates.Angle.__new__
方法和at Longitude
那里 astropy.coordinates.Longitude.__array_finalize__
方法用于传递经度缠绕的角度。
另一个要被子类重写的方法,特定于 Quantity
是 astropy.units.Quantity.__quantity_subclass__
. 调用此函数是为了根据 Quantity
那将被创造出来。例如,它用于 Angle
归还 Quantity
如果计算返回的单位不是角度单位。这是通过 SpecificTypeQuantity
,这通常允许用户构造 Quantity
子类的方法只对特定的物理类型有用。