结构化单元#

块状数组可以是 structured arrays ,其中每个元素由多个字段组成。这些可以与一起使用 Quantity 使用 StructuredUnit ,它提供了一个 UnitBase 对于每个字段。例如,这允许构建单个 Quantity 具有具有不同单位的位置和速度场的对象,但包含在同一对象中(根据需要支持 PyERFA 用包装纸包裹着 ERFA 使用位置-速度数组的例程)。

创建结构化土方#

可以直接创建结构化数量,也可以通过与 StructuredUnit ,后者可以直接创建,也可以通过 Unit

例子#

要创建包含位置和速度的结构化数量,请执行以下操作:

>>> import astropy.units as u, numpy as np
>>> pv_values = np.array([([1., 0., 0.], [0., 0.125, 0.]),
...                       ([0., 1., 0.], [-0.125, 0., 0.])],
...                      dtype=[('p', '(3,)f8'), ('v', '(3,)f8')])
>>> pv = u.Quantity(pv_values, u.StructuredUnit((u.km, u.km/u.s)))
>>> pv
<Quantity [([1., 0., 0.], [ 0.   ,  0.125,  0.   ]),
           ([0., 1., 0.], [-0.125,  0.   ,  0.   ])] (km, km / s)>
>>> pv_values * u.Unit('AU, AU/day')
<Quantity [([1., 0., 0.], [ 0.   ,  0.125,  0.   ]),
           ([0., 1., 0.], [-0.125,  0.   ,  0.   ])] (AU, AU / d)>

至于正常 Quantity 对象,则可以使用 valueunit 属性。此外,您还可以使用其名称::为任何给定的字段编制索引

>>> pv = pv_values * u.Unit('km, km/s')
>>> pv.value
array([([1., 0., 0.], [ 0.   ,  0.125,  0.   ]),
       ([0., 1., 0.], [-0.125,  0.   ,  0.   ])],
      dtype=[('p', '<f8', (3,)), ('v', '<f8', (3,))])
>>> pv.unit
Unit("(km, km / s)")
>>> pv['v']
<Quantity [[ 0.   ,  0.125,  0.   ],
           [-0.125,  0.   ,  0.   ]] km / s>

结构可以嵌套,如本例中取自 PyERFA 测试用例 erfa.ldn() **

>>> ldbody = [
...     (0.00028574, 3e-10, ([-7.81014427, -5.60956681, -1.98079819],
...                          [0.0030723249, -0.00406995477, -0.00181335842])),
...     (0.00095435, 3e-9, ([0.738098796, 4.63658692, 1.9693136],
...                         [-0.00755816922, 0.00126913722, 0.000727999001])),
...     (1.0, 6e-6, ([-0.000712174377, -0.00230478303, -0.00105865966],
...                  [6.29235213e-6, -3.30888387e-7, -2.96486623e-7]))
...     ] * u.Unit('Msun,radian,(AU,AU/day)')
>>> ldbody  
<Quantity [(2.8574e-04, 3.e-10, ([-7.81014427e+00, -5.60956681e+00, -1.98079819e+00], [ 3.07232490e-03, -4.06995477e-03, -1.81335842e-03])),
           (9.5435e-04, 3.e-09, ([ 7.38098796e-01,  4.63658692e+00,  1.96931360e+00], [-7.55816922e-03,  1.26913722e-03,  7.27999001e-04])),
           (1.0000e+00, 6.e-06, ([-7.12174377e-04, -2.30478303e-03, -1.05865966e-03], [ 6.29235213e-06, -3.30888387e-07, -2.96486623e-07]))] (solMass, rad, (AU, AU / d))>

转换为不同单位#

就像普通的 Quantity 对于对象,只要它们具有相同的结构且每个单位相等,就可以将结构量转换为不同的单位。

例子#

要将结构土方量转换为其他单位,请执行以下操作:

>>> pv.to((u.m, u.m / u.s))  
<Quantity [([1000.,    0.,    0.], [   0.,  125.,    0.]),
           ([   0., 1000.,    0.], [-125.,    0.,    0.])] (m, m / s)>
>>> pv.cgs
<Quantity [([100000.,      0.,      0.], [     0.,  12500.,      0.]),
           ([     0., 100000.,      0.], [-12500.,      0.,      0.])] (cm, cm / s)>

与ERFA一起使用#

这个 ERFA C例程利用结构化类型,这些类型在 PyERFA 界面。

警告

不是全部 PyERFA 例行公事还没有结束。帮助添加包装纸将不胜感激。

例子#

要将位置-速度结构数组与 PyERFA **

>>> import erfa
>>> pv_values = np.array([([1., 0., 0.], [0., 0.125, 0.]),
...                       ([0., 1., 0.], [-0.125, 0., 0.])],
...                      dtype=erfa.dt_pv)
>>> pv = pv_values << u.Unit('AU,AU/day')
>>> erfa.pvu(86400*u.s, pv)
<Quantity [([ 1.   ,  0.125,  0.   ], [ 0.   ,  0.125,  0.   ]),
           ([-0.125,  1.   ,  0.   ], [-0.125,  0.   ,  0.   ])] (AU, AU / d)>
>>> erfa.pv2s(pv)  
(<Quantity [0.        , 1.57079633] rad>,
 <Quantity [0., 0.] rad>,
 <Quantity [1., 1.] AU>,
 <Quantity [0.125, 0.125] rad / d>,
 <Quantity [0., 0.] rad / d>,
 <Quantity [0., 0.] AU / d>)
>>> z_axis = np.array(([0, 0, 1], [0, 0, 0]), erfa.dt_pv) * u.Unit('1,1/s')
>>> erfa.pvxpv(pv, z_axis)
<Quantity [([ 0., -1.,  0.], [0.125, 0.   , 0.   ]),
           ([ 1.,  0.,  0.], [0.   , 0.125, 0.   ])] (AU, AU / d)>