NDData#

概述#

NDData 基于 numpy.ndarraydata 使用其他元属性:

  • meta 对于常规元数据

  • unit 表示数据的物理单位

  • uncertainty 因为数据的不确定性

  • mask 指示数据中的无效点

  • wcs 表示数据网格和世界坐标之间的关系

  • psf 保存点扩展函数(PSF)的图像表示

这些属性中的每一个都可以在初始化期间设置,也可以直接在实例上设置。只有 data 无法在创建实例后直接设置。

数据#

数据是 NDData 必须是 numpy.ndarray -就像。它是创建实例所需的唯一属性,不能直接在实例上设置。

例子#

要创建实例:

>>> import numpy as np
>>> from astropy.nddata import NDData
>>> array = np.array([[0, 1, 0], [1, 0, 1], [0, 1, 0]])
>>> ndd = NDData(array)
>>> ndd
NDData([[0, 1, 0],
        [1, 0, 1],
        [0, 1, 0]])

通过 data 属性:

>>> ndd.data
array([[0, 1, 0],
       [1, 0, 1],
       [0, 1, 0]])

如前所述,不可能直接设置数据。所以 ndd.data = np.arange(9) 将引发异常。但数据可以就地修改:

>>> ndd.data[1,1] = 100
>>> ndd.data
array([[  0,   1,   0],
       [  1, 100,   1],
       [  0,   1,   0]])

初始化期间的数据#

在初始化期间,可以提供不是 numpy.ndarray 但可以转换成一个。

实例#

提供可转换为 numpy.ndarray ,你可以通过 list 包含数值:

>>> alist = [1, 2, 3, 4]
>>> ndd = NDData(alist)
>>> ndd.data  # data will be a numpy-array:
array([1, 2, 3, 4])

嵌套的 listtuple 可能,但如果这些值包含非数值,则转换可能失败。

除了可以转换为这样一个数组的输入之外,还可以使用 data 参数传递隐式附加信息。例如,如果数据是另一个 NDData 对象它隐式使用其属性::

>>> ndd = NDData(ndd, unit = 'm')
>>> ndd2 = NDData(ndd)
>>> ndd2.data  # It has the same data as ndd
array([1, 2, 3, 4])
>>> ndd2.unit  # but it also has the same unit as ndd
Unit("m")

另一种可能是使用 Quantity 作为一个 data 参数::

>>> import astropy.units as u
>>> quantity = np.ones(3) * u.cm  # this will create a Quantity
>>> ndd3 = NDData(quantity)
>>> ndd3.data  
array([1., 1., 1.])
>>> ndd3.unit
Unit("cm")

或者 numpy.ma.MaskedArray ::

>>> masked_array = np.ma.array([5,10,15], mask=[False, True, False])
>>> ndd4 = NDData(masked_array)
>>> ndd4.data
array([ 5, 10, 15])
>>> ndd4.mask
array([False,  True, False]...)

如果这种隐式传递的属性与显式参数冲突,则将使用显式参数并发出一条信息消息:

>>> quantity = np.ones(3) * u.cm
>>> ndd6 = NDData(quantity, unit='m')
INFO: overwriting Quantity's current unit with specified unit. [astropy.nddata.nddata]
>>> ndd6.data  
array([0.01, 0.01, 0.01])
>>> ndd6.unit
Unit("m")

单位 Quantity 将被忽略,并将单元设置为显式传递的单位。

也可以通过其他类作为 data 参数只要它们具有属性 shapedtype__getitem____array__ .

此机制的目的是在提供有用的默认值的同时,允许用于存储数据的对象具有相当大的灵活性 (numpy 阵列)。

面具#

这个 mask 用于指示数据点是否有效。 NDData 不会以任何方式限制此掩码,但它应该遵循 numpy.ma.MaskedArray 传统的面具:

  • 返回 True 对于考虑的数据点 无效 .

  • 返回 False 对于那些 有效的 .

实例#

一种方法是使用 numpy 的比较运算符::

>>> array = np.array([0, 1, 4, 0, 2])

>>> mask = array == 0  # Mask points containing 0
>>> mask
array([ True, False, False,  True, False]...)

>>> other_mask = array > 1  # Mask points with a value greater than 1
>>> other_mask
array([False, False,  True, False,  True]...)

并初始化 NDData 实例使用 mask 参数::

>>> ndd = NDData(array, mask=mask)
>>> ndd.mask
array([ True, False, False,  True, False]...)

或者更换面罩:

>>> ndd.mask = other_mask
>>> ndd.mask
array([False, False,  True, False,  True]...)

没有要求面具实际上是 numpy 数组;例如,根据需要计算掩码值的函数是可以接受的,只要它遵循以下约定 True 指示应忽略的值。

单位#

这个 unit 表示数据值的单位。这是必须的 Unit -或者一个可以转换为 Unit ::

>>> import astropy.units as u
>>> ndd = NDData([1, 2, 3, 4], unit="meter")  # using a string
>>> ndd.unit
Unit("m")
..注:

设置 unit 在实例上是不可能的。

不确定性#

这个 uncertainty 表示数据值错误的任意表示形式。为了指示使用哪种不确定度表示,使用 uncertainty 应该有一个 uncertainty_type 财产。如果没有找到这样的属性,它将被包装在 UnknownUncertainty .

这个 uncertainty_type 应该遵循 StdDevUncertainty 它返回一个短字符串 "std" 对于标准偏差中给出的不确定度。其他例子有 VarianceUncertaintyInverseVariance .

实例#

与其他属性一样 uncertainty 可在初始化期间设置:

>>> from astropy.nddata import StdDevUncertainty, InverseVariance
>>> array = np.array([10, 7, 12, 22])
>>> uncert = StdDevUncertainty(np.sqrt(array))
>>> ndd = NDData(array, uncertainty=uncert)
>>> ndd.uncertainty  
StdDevUncertainty([3.16227766, 2.64575131, 3.46410162, 4.69041576])

或者直接在实例上:

>>> other_uncert = StdDevUncertainty([2,2,2,2])
>>> ndd.uncertainty = other_uncert
>>> ndd.uncertainty
StdDevUncertainty([2, 2, 2, 2])

但是如果没有,它会打印一条信息消息 uncertainty_type ::

>>> ndd.uncertainty = np.array([5, 1, 2, 10])
INFO: uncertainty should have attribute uncertainty_type. [astropy.nddata.nddata]
>>> ndd.uncertainty
UnknownUncertainty([ 5,  1,  2, 10])

还可以在不确定类型之间进行转换:

>>> uncert.represent_as(InverseVariance)
InverseVariance([0.1       , 0.14285714, 0.08333333, 0.04545455])

WCS#

这个 wcs 应该包含从网格数据到世界坐标的映射。目前对该物业没有任何限制,但可能仅限于 WCS 对象或将来更通用的WCS对象。

备注

就像这个单位 wcs 无法在实例上设置。

元数据#

这个 meta 属性包含不适合任何其他属性的所有进一步的元信息。

实例#

如果 meta 属性必须是 dict -比如:

>>> ndd = NDData([1,2,3], meta={'observer': 'myself'})
>>> ndd.meta
{'observer': 'myself'}

dict -like意味着它必须是从一些键到某些值的映射。这还包括 Header 物体::

>>> from astropy.io import fits
>>> header = fits.Header()
>>> header['observer'] = 'Edwin Hubble'
>>> ndd = NDData(np.zeros([10, 10]), meta=header)
>>> ndd.meta['observer']
'Edwin Hubble'

如果 meta 属性未提供或显式设置为 None ,它将默认为空 collections.OrderedDict ::

>>> ndd.meta = None
>>> ndd.meta
OrderedDict()

>>> ndd = NDData([1,2,3])
>>> ndd.meta
OrderedDict()

这个 meta 对象因此支持添加或更新这些值:

>>> ndd.meta['exposure_time'] = 340.
>>> ndd.meta['filter'] = 'J'

元数据字典的元素可以设置为任何有效的Python对象:

>>> ndd.meta['history'] = ['calibrated', 'aligned', 'flat-fielded']

使用复制初始化#

创建 NDData 实例将尝试将参数保存为对原始参数的引用而不是副本。有时这是不可能的,因为内部机制不允许这样做。

实例#

如果 data 是一个 list 然后在初始化过程中,在转换为 ndarray . 但也可以通过设置 copy 参数到 True ::

>>> array = np.array([1, 2, 3, 4])
>>> ndd = NDData(array)
>>> ndd.data[2] = 10
>>> array[2]  # Original array has changed
10

>>> ndd2 = NDData(array, copy=True)
>>> ndd2.data[2] = 3
>>> array[2]  # Original array hasn't changed.
10

备注

在某些情况下 copy=True 将复制 data 两次。已知的情况是如果 data 是一个 listtuple .

沿一个或多个轴折叠NDData对象#

一种常见的操作 ndarray 是沿着一个或多个轴求和、平均值、最大值或最小值,从而降低输出的维度。这四个操作是在 NDData 适当地传播不确定因素、掩码和单元。

例如,让我们做以下工作 data 使用遮罩、单位和(统一)不确定性::

>>> import numpy as np
>>> import astropy.units as u
>>> from astropy.nddata import NDDataArray, StdDevUncertainty
>>>
>>> data = [
...     [1, 2, 3],
...     [2, 3, 4]
... ]
>>> mask = [
...     [True, False, False],
...     [False, False, False]
... ]
>>> uncertainty = StdDevUncertainty(np.ones_like(data))
>>> nddata = NDDataArray(data=data, uncertainty=uncertainty, mask=mask, unit='m')

沿轴的总和 1 每行提供一个结果::

>>> sum_axis_1 = nddata.sum(axis=1)  # this is a new NDDataArray
>>> print(np.asanyarray(sum_axis_1))  # this converts data to a numpy masked array. doctest: +FLOAT_CMP
[-- 9.0]
>>> print(sum_axis_1.uncertainty)  
StdDevUncertainty([1.41421356, 1.73205081])

结果具有一个屏蔽值,该值派生自原始掩码的逻辑或 axis=1 。不确定性是输入不确定性平方和的平方根。由于最初的不确定性都是统一的,因此结果是未屏蔽数据条目数量的平方根, \([\sqrt{2},\,\sqrt{3}]\)

同样,我们也可以采用平均数。 axis=1 **

>>> mean_axis_1 = nddata.mean(axis=1)
>>> print(np.asanyarray(mean_axis_1))  
[2.5 3.0]
>>> print(mean_axis_1.uncertainty)  
StdDevUncertainty([0.70710678, 0.57735027])

结果是值的平均值,其中 mask==False ,在本例中,结果将只有 mask==True 如果整行都被屏蔽了。由于不确定性被给出为 StdDevUncertainty ,传播的不确定度与每行中无掩码测量的数量成正比地减小,如下 \([2^{-1/2},\,3^{-1/2}]\)

没有一种单一的、正确的方法来定义与 minmax 一组测量结果,所以 NDData 抵制猜测的诱惑,并返回沿轴的最小数据值和传播的遮罩,但不存在不确定性:

>>> min_axis_1 = nddata.min(axis=1)
>>> print(np.asanyarray(min_axis_1))  
[2.0 2.0]
>>> print(min_axis_1.uncertainty)
None

对于某些用例,以与最小/最大值相同的索引返回不确定性可能会有所帮助 data 值,以便原始的 data 保持了它的不确定性。您可以使用::获取此行为

>>> min_axis_1 = nddata.min(axis=1, propagate_uncertainties=True)

>>> print(np.asanyarray(min_axis_1))  
[2.0 2.0]
>>> print(min_axis_1.uncertainty)  
StdDevUncertainty([1, 1])

最后,在某些情况下,仅对未掩码的值执行折叠操作,并且仅在所有输入值都被掩码时返回掩码结果可能是有用的。如果我们参考本节中的第一个示例,我们会看到底层的 data 属性已对所有值求和,包括掩码值::

>>> sum_axis_1  
NDDataArray([——, 9.], unit='m')

其中第一数据元素被屏蔽。方法,我们只能获得非屏蔽值的总和。 operation_ignores_mask 选项::

>>> nddata.sum(axis=1, operation_ignores_mask=True)
NDDataArray([5, 9], unit='m')

将NDData转换为其他类#

对转换 NDData 实例到其他类。在此过程中,某些属性可能会丢失。

>>> data = np.array([1, 2, 3, 4])
>>> mask = np.array([True, False, False, True])
>>> unit = 'm'
>>> ndd = NDData(data, mask=mask, unit=unit)

numpy.ndarray#

转换 data 到数组:

>>> array = np.asarray(ndd.data)
>>> array
array([1, 2, 3, 4])

尽管使用 np.asarray 在大多数情况下,它将确保结果始终是 numpy.ndarray

numpy.ma.MaskedArray#

转换 datamask 对一个面具师说:

>>> masked_array = np.ma.array(ndd.data, mask=ndd.mask)
>>> masked_array
masked_array(data=[--, 2, 3, --],
             mask=[ True, False, False,  True],
       fill_value=999999)

Quantity#

转换 dataunit 数量:

>>> quantity = u.Quantity(ndd.data, unit=ndd.unit)
>>> quantity  
<Quantity [1., 2., 3., 4.] m>

MaskedQuantity#

dataunit ,以及 mask 到一个 MaskedQuantity **

>>> from astropy.utils.masked import Masked
>>> Masked(u.Quantity(ndd.data, ndd.unit), ndd.mask)  
<MaskedQuantity [——, 2., 3., ——] m>