统一文件读写接口

astropy 为不同格式的数据读写提供统一的接口。对于许多常见的情况,这将简化文件I/O的过程,并减少掌握中所有I/O包的单独细节的需要 astropy . 有关实现的详细信息,请参见 I/O注册表 (astropy.io.registry ) .

映像I/O入门

支持在统一I/O接口中读写图像数据 CCDData 使用FITS文件格式初始化:

>>> # Read CCD image
>>> ccd = CCDData.read('image.fits')
>>> # Write back CCD image
>>> ccd.write('new_image.fits')

请注意,该单元存储在 BUNIT 关键字,如果存在,则从标头中读取。

有关读写可用关键字参数的详细帮助,可以通过 help() 方法如下:

>>> CCDData.read.help('fits')  # Get help on the CCDData FITS reader
>>> CCDData.writer.help('fits')  # Get help on the CCDData FITS writer

开始使用表I/O

这个 Table 类包括两个方法, read()write() ,这使得读写文件成为可能。自动支持多种格式(请参见 Built-in table readers/writers )新的文件格式和扩展名可以注册到 Table 类(见) I/O注册表 (astropy.io.registry )

实例

要使用此接口,请首先导入 Table 同学们,然后打电话给 Table read() 方法,例如文件名和文件格式 'ascii.daophot'

>>> from astropy.table import Table
>>> t = Table.read('photometry.dat', format='ascii.daophot')

可以使用url直接从Internet加载表。例如,从Vizier目录下载CD格式的表格 ('ascii.cds' ):

>>> t = Table.read("ftp://cdsarc.u-strasbg.fr/pub/cats/VII/253/snrs.dat",
...         readme="ftp://cdsarc.u-strasbg.fr/pub/cats/VII/253/ReadMe",
...         format="ascii.cds")  

对于某些文件格式,可以自动检测格式,例如,从文件扩展名:

>>> t = Table.read('table.tex')  

对于写入表,可以显式指定格式:

>>> t.write(filename, format='latex')  

至于 read() 方法,在某些情况下可能会自动识别格式。

底层文件处理程序还将自动检测各种压缩数据格式,并在Python安装支持的范围内透明地解压缩它们(请参见 get_readable_fileobj()

对于编写,还可以指定有关 Table serialization methods 通过 serialize_method 关键字参数。这允许精确控制写出某些列的方式,例如将ISO格式的时间列作为一对JD1/JD2浮点值(用于完全解析)或格式化的ISO日期字符串。

获取读者和作家的帮助

每个文件格式都由特定的读取器或编写器处理,并且每个函数都有自己的参数集。有关这方面的示例,请参阅部分 Built-in table readers/writers . 本节还提供了 format 争论。

若要获取有关每种格式的可用参数的帮助,请使用 help() 方法 readwrite 方法。每个调用都会打印一个较长的帮助文档,该文档分为两个部分:通用读/写文档(任何调用都通用)和特定于格式的文档。对于ASCII表,格式特定的文档包括 astropy.io.ascii 包接口,然后描述特定的ASCII子格式。

在下面的示例中,我们没有显示长输出:

>>> Table.read.help('fits')
>>> Table.read.help('ascii')
>>> Table.read.help('ascii.latex')
>>> Table.write.help('hdf5')
>>> Table.write.help('csv')

命令行实用程序

为了方便起见,命令行工具 showtable 可用于打印统一I/O接口支持的格式的表内容。

例子

要在命令行上查看表的内容,请执行以下操作:

$ showtable astropy/io/fits/tests/data/table.fits

 target V_mag
------- -----
NGC1001  11.1
NGC1002  12.3
NGC1003  15.2

要获取有关用法和可用选项的完整文档,请执行以下操作: showtable --help .

内置表读写器

这个 Table 类具有对各种输入和输出格式的内置支持,包括 ASCII格式 , -FITSHDF5PandasVO表 .

支持的格式和相应的类的完整列表如下表所示。这个 Write 列指示那些支持写入功能的格式,以及 Suffix 列指示指示特定格式的文件名后缀。如果 Suffixauto ,则从文件本身自动检测格式。并非所有格式都支持自动检测。

格式

后缀

描述

ASCII码

是的

任何支持格式的ASCII表(使用猜测)

ascii.aastex

是的

AASTex :用于AAS期刊的AASTeX deluxetable

ascii.basic

是的

Basic :带自定义分隔符的基本表

ascii.cds

Cds :CDS格式表

ascii.commented_header

是的

CommentedHeader :注释行中的列名

ascii.csv

是的

.csv文件

Csv :带有逗号分隔值的基本表

ascii.daophot

Daophot :IRAF DAOphot格式表

ascii.ecsv

是的

.ecsv系统

Ecsv :具有增强CSV的基本表(支持元数据)

ascii.fixed_width

是的

FixedWidth :固定宽度

ascii.fixed_width_no_header

是的

FixedWidthNoHeader :固定宽度,无标题

ascii.fixed_width_two_line

是的

FixedWidthTwoLine :具有第二条标题行的固定宽度

ascii.html

是的

.html格式

HTML :HTML表格

ascii.ipac

是的

Ipac :IPAC格式表

ascii.latex

是的

.tex公司

Latex : Latex 表

ascii.no_header

是的

NoHeader :没有标题的基本表

ascii.rdb

是的

.rdb文件

Rdb :用类型定义标题行分隔的选项卡

ascii.rst

是的

.重新设置

RST :restructedText简单格式表

ascii.sextractor

SExtractor :SExtractor格式表

ascii.tab

是的

Tab :带制表符分隔值的基本表

适合

是的

汽车

fits :灵活的图像传输系统文件

hdf5型

是的

汽车

分层数据格式二进制文件

pandas.csv

是的

环绕包装 pandas.read_csv()pandas.to_csv()

pandas.fwf

环绕包装 pandas.read_fwf() (固定宽度格式)

pandas.html

是的

环绕包装 pandas.read_html()pandas.to_html()

pandas.json

是的

环绕包装 pandas.read_json()pandas.to_json()

可听的

是的

汽车

votable :虚拟天文台(VO)计划使用的表格格式

ASCII格式

这个 read()write() 方法可用于读取和写入受支持的格式 astropy.io.ascii .

使用 format='ascii' 为了接口到泛型 read()write() 功能从 astropy.io.ascii . 读取表时,这意味着将尝试所有支持的ASCII表格式,以便成功解析输入。

实例

读写支持的格式 astropy.io.ascii

>>> t = Table.read('astropy/io/ascii/tests/t/latex1.tex', format='ascii')
>>> print(t)
cola colb colc
---- ---- ----
   a    1    2
   b    3    4

写表格时 format='ascii' 输出是一个基本字符分隔的文件,其中只有一个标题行包含列名。

所有附加参数都传递给 astropy.io.ascii read()write() 功能。有关详细信息,请参阅 参数用于 read()参数用于 write() . 例如,更改列分隔符和 colc 列用途:

>>> t.write(sys.stdout, format='ascii', delimiter='|', formats={'colc': '%0.2f'})
cola|colb|colc
a|1|2.00
b|3|4.00

注解

当使用统一接口指定ASCII表格格式时,格式名称的前缀为 ascii 以识别基于ASCII的格式。将上表与 astropy.io.ascii 名单 supported formats 不需要前缀的地方。因此,以下内容等效:

  >>> dat = ascii.read('file.dat', format='daophot')
  >>> dat = Table.read('file.dat', format='ascii.daophot')

For compatibility with ``astropy`` version 0.2 and earlier, the following
format values are also allowed in ``Table.read()``: ``daophot``, ``ipac``,
``html``, ``latex``, and ``rdb``.

注意

建议使用ECSV

对于以完全复制表数据、类型和元数据(即,表将“往返”)的方式将表写入和读取到ASCII,我们强烈建议使用 ECSV格式 . 这将以空格分隔的格式写入实际数据( basic 格式),任何ASCII表读取器都可以解析,但也包括注释块中编码的元数据,该注释块允许完全重建原始列。这包括支持 混合柱 (如 SkyCoordTime遮罩柱 .

FITS

读写表格 FITS 格式支持 format='fits' . 在大多数情况下,现有的FITS文件应该根据文件头自动标识出来,但是如果没有,或者如果写入磁盘,则应该显式指定格式。

阅读

如果FITS表文件只包含一个表,则可以使用以下命令读入:

>>> from astropy.table import Table
>>> t = Table.read('data.fits')

如果文件中存在多个表,可以按如下方式选择HDU::

>>> t = Table.read('data.fits', hdu=3)  

在这种情况下,如果 hdu 参数,则将读入找到的第一个表并发出警告:

>>> t = Table.read('data.fits')  
WARNING: hdu= was not specified but multiple tables are present, reading in first available table (hdu=1) [astropy.io.fits.connect]

您也可以从内存FITS文件的hdu读取表。这将往返任何 混合柱 它们被写入HDU,使用头信息来重建它们:

>>> hdulist = astropy.io.fits.open('data.fits') 
>>> t = Table.read(hdulist[1])  

写作

写表格 t 到新文件:

>>> t.write('new_table.fits')  

如果文件已经存在并且您想覆盖它,则设置 overwrite 关键词:

>>> t.write('existing_table.fits', overwrite=True)  

此时,不支持将HDU附加到现有文件或使用Table接口写入多个HDU文件。相反,您可以使用便利功能 table_to_hdu() 创建单个二进制表HDU并将其插入或附加到现有的 HDUList .

至于 astropy 版本3.0支持编写包含 混合柱TimeSkyCoord . 这个用的是FITS COMMENT 当从FITS中读回时,捕捉额外信息的卡片需要顺序来完全重建mixin列。信息是一条 Python dict 结构,它使用YAML序列化。

关键词

与HDU表相关联的FITS关键字在 meta 的有序字典属性 Table . 阅读表格后,您可以使用以下命令以可读格式查看可用关键字:

>>> for key, value in t.meta.items():
...     print(f'{key} = {value}')

这不包括指定FITS表属性所需的“internal”FITS关键字(例如。, NAXISTTYPE1HISTORYCOMMENT 关键字被特殊处理并作为值列表返回。

相反,下面显示了为表设置用户关键字值的示例 t

>>> t.meta['MY_KEYWD'] = 'my value'
>>> t.meta['COMMENT'] = ['First comment', 'Second comment', 'etc']
>>> t.write('my_table.fits', overwrite=True)

关键字名称(例如。, MY_KEYWD )将在写入前自动大写。

在这个时候 meta 的属性 Table 类是一个有序字典,不能完全表示FITS头的结构(例如,删除关键字注释)。

TDISPn关键字

TDISPn FITS关键字将映射到 Column format 属性,如果显示格式可以转换为Python显示格式和从Python显示格式转换。下面是两个转换方向使用的规则。

TDISPn到Python格式字符串

TDISPn格式字符定义见下表。

格式

描述

性格

Lw公司

合乎逻辑的

Iw.m

整数

Bw.m

二进制,仅整数

Ow.m

八进制,仅整数

Zw.m

十六进制,仅整数

Fw.d

浮点,固定十进制记数法

Ew.dEe

浮点,指数表示法

ENw.d

工程;指数倍数为3的E格式

ESw.d

科学;与EN相同,但如果不为零,则前导数字不为零

Gw.dEe

一般的;如果意义没有丢失,也就是E

Dw.dEe

浮点,指数表示法,双精度

其中w是显示值的字符宽度,m是显示的最小位数,d是小数点右边的位数,e是指数中的位数。.m和Ee字段是可选的。

A(字符)、L(逻辑)、F(浮点)和G(通用)显示格式可以直接转换为Python格式的字符串。其他格式需要修改以匹配Python显示格式。

对于整数格式(I、B、O和Z),width(w)值用于在列值的左侧添加空格填充。不使用最小数字(m)值。对于E、G、D、EN和ES格式(浮点指数),宽度(w)和精度(D)都使用,但指数(E)没有使用。

Python格式字符串到TDISPn

从Python格式字符串到TDISPn的转换稍微复杂一些。

如果Python格式化字符串不包含正确的空格填充,则Python字符串映射到TDISP格式A。它将接受左空格填充。逻辑格式L也是如此。

整数格式(十进制整数、二进制、八进制、十六进制)分别映射到I、B、O和Z TDISP格式。整数格式不接受零填充格式字符串或未定义左填充的格式字符串(整数格式的TDISP格式标准中要求宽度)。

对于所有浮点值和指数值,不接受零填充。必须至少定义宽度或精度。如果只定义了宽度,则TDISPn格式没有精度设置。如果只定义了一个精度,则宽度设置为精度加上一个额外的填充值(取决于格式类型),两者都以TDISPn格式设置。否则,如果同时存在宽度和精度,则均以TDISPn格式设置。 Python fF 映射到TDISP F格式。 Python gG 映射到TDISP G格式。 Python eE 映射到TDISP E格式。

遮罩柱

包含 MaskedColumn 列可以按大小写。默认情况下,根据FITS标准,这将用特定的哨兵值替换屏蔽的数据元素:

  • NaN 对于浮动列。

  • 价值 TNULLn 对于整数列,由列定义 fill_value 属性。

  • 字符串列的空字符串(当前未实现)。

当文件被读回时,这些元素在返回的表中被标记为掩码,但是请参见 issue #4708 三种情况下都有问题。

FITS标准有一些限制:

  • 并非所有数据类型都受支持(例如,逻辑/布尔)。

  • 整数列需要选择一个值作为空指示符。如果所有可能的值都用有效数据表示(例如,在有效数据中包含256个可能值的无符号int列),则无法表示缺失的数据。

  • 屏蔽的数据值将永久丢失,从而排除了以后取消屏蔽这些值的可能性。

astropy 提供了一个解决此限制的方法,用户可以选择使用。关键是使用 serialize_method='data_mask' 写入表时的关键字参数。这告诉FITS编写器将每个屏蔽列拆分为两个单独的列,一个用于数据,另一个用于掩码。当它被读回时,这个过程是反向的,两列合并回一个屏蔽列。

>>> from astropy.table.table_helpers import simple_table
>>> t = simple_table(masked=True)
>>> t['d'] = [False, False, True]
>>> t['d'].mask = [True, False, False]
>>> t
<Table masked=True length=3>
  a      b     c     d
int64 float64 str1  bool
----- ------- ---- -----
   --     1.0    c    --
    2     2.0   -- False
    3      --    e  True
>>> t.write('data.fits', serialize_method='data_mask', overwrite=True)
>>> Table.read('data.fits')
<Table masked=True length=3>
  a      b      c      d
int64 float64 bytes1  bool
----- ------- ------ -----
   --     1.0      c    --
    2     2.0     -- False
    3      --      e  True

警告

此选项超出了现有的FITS表示缺失数据的标准,因此用户应谨慎选择此选项,尤其是当其他(非“astropy”)用户将要读取文件时。在幕后, astropy 正在将掩码列转换为两个不同的数据列和掩码列,然后将元数据写入 COMMENT 允许重建原始数据的卡。

astropy 本机对象(Mixin列)

不仅可以存储标准 Column 对象到FITS表HDU,也可以是任何 astropy 本机对象 (混合柱 )在一个 TableQTable . 这包括 TimeQuantitySkyCoord 以及其他许多人。

通常,mixin列可能包含多个数据组件以及标准列属性之外的对象属性,例如 formatdescription . 遵守FITS标准设置的规则需要将这些数据组件和对象属性映射到适当的FITS表列和关键字。因此,已经开发了一个定义良好的协议,允许在FITS中存储这些mixin列,同时允许对象在不丢失数据或属性的情况下“往返”文件。

数量

A Quantity a中的混合柱 QTable 在FITS表中使用 TUNITn 适合列关键字合并数量的单位属性。例如:

>>> from astropy.table import QTable
>>> import astropy.units as u
>>> t = QTable([[1, 2] * u.angstrom)])
>>> t.write('my_table.fits', overwrite=True)
>>> qt = QTable.read('my_table.fits')
>>> qt
<QTable length=2>
  col0
Angstrom
float64
--------
     1.0
     2.0
时间

astropy 阅读和写作具有以下特点 Time

  • 写作和阅读 Time 表格列与表格之间的匹配。

  • 读取FITS表(符合时间标准)中的时间坐标列作为 Time 表列。

写作和阅读 astropy 时间列

默认情况下,A Time 混合柱 TableQTable 将以完全精确的方式编写。这将通过设置必要的FITS标题关键字来使用FITS时间标准来完成。

读取表符合默认行为 Table 一直以来都是将“全能型”柱转换为 Column 对象,这些对象具有密切匹配的属性。但是,对于某些列,更接近于本机 astropy 表示是可能的,您可以通过传递来指示这些表示 astropy_native=True (为了向后兼容,默认情况下不会这样做)。这将把符合FITS时间标准的列转换为 Time 实例,避免任何精度损失。

例子

读入FITS表 Table

>>> from astropy.time import Time
>>> from astropy.table import Table
>>> from astropy.coordinates import EarthLocation
>>> t = Table()
>>> t['a'] = Time([100.0, 200.0], scale='tt', format='mjd',
...               location=EarthLocation(-2446354, 4237210, 4077985, unit='m'))
>>> t.write('my_table.fits', overwrite=True)
>>> tm = Table.read('my_table.fits', astropy_native=True)
>>> tm['a']
<Time object: scale='tt' format='jd' value=[ 2400100.5  2400200.5]>
>>> tm['a'].location
<EarthLocation (-2446354.,  4237210.,  4077985.) m>
>>> all(tm['a'] == t['a'])
True

同样适用于 QTable .

除了二进制表列外,各种全局时间信息拟合关键字都是用 astropy_native=True . 尤其是关键字 DATEDATE-* (ISO 8601日期时间字符串),以及 MJD-* (MJD日期值)将返回为 Time 表中的对象 meta . 有关FITS时间文件和实现的更多详细信息,请参阅 适合具有时间列的表格 .

由于并非所有的FITS阅读器都能使用FITS时间标准,因此也可以存储 Time instances using the _ time_format `. For this case, none of the special header keywords associated with the FITS time standard will be set. When reading this back into ``astropy`, the column will be an ordinary Column instead of a Time object. See the Details 下面是一个例子。

读取适合二进制表中符合标准的时间坐标列

支持读取符合FITS时间标准的FITS文件 astropy 遵循标准规定的各种规则和惯例。设计该标准的目的是以明确和全面的方式描述时间坐标,并为其多个用例提供灵活性。因此,在读取符合FITS的文件中的时间坐标列时,需要考虑标准的多个方面。

时间坐标列严格符合标准的双矢量JD子集(在 Details 以下部分)可以读为本机 Time 物体。本标准的其他子集也由 astropy 对FITS标准时间相关关键字进行了全面检查,并对时间数据进行了相应的解释。

本标准描述了时间规范中的各个组成部分:

  • 时间坐标

  • 时间单位

  • 更正、错误等。

  • 持续时间

用于指定时间的关键字定义这些组件。使用这些关键字,时间坐标列被标识为 Time 物体。参考 适合具有时间列的表格 对于这些关键字的规范及其描述。

标准有两个方面需要特别注意,因为在处理它们时涉及到微妙的问题。这些是:

  • 名为TIME和TIME unit的列

现有FITS文件中的一个常见约定是FITS二进制表列 TTYPEn = ‘TIME’ 表示时间坐标列。许多天文数据文件,包括来自主要天文台的官方数据产品,都遵循这一先于FITS标准的惯例。FITS时间标准声明这样的列将由全局时间参考帧关键字控制,并且这仍然符合当前标准。

使用已纳入本标准的本公约, astropy 可以从所有这样的FITS表中读取时间坐标列 Time 物体。遵循此约定的FITS文件的常见示例是Chandra、XMM和HST文件。

实例

以下是Chandra事件列表的标题提取示例:

COMMENT      ---------- Globally valid key words ----------------
DATE    = '2016-01-27T12:34:24' / Date and time of file creation
TIMESYS = 'TT      '           / Time system
MJDREF  =  5.0814000000000E+04 / [d] MJD zero point for times
TIMEUNIT= 's       '           / Time unit
TIMEREF = 'LOCAL   '           / Time reference (barycenter/local)

COMMENT      ---------- Time Column -----------------------
TTYPE1  = 'time    '           / S/C TT corresponding to mid-exposure
TFORM1  = '1D      '           / format of field
TUNIT1  = 's       '

当阅读这样一个适合的表格 astropy_native=Trueastropy 检查列的名称是否为“TIME”/“TIME” (TTYPEn = ‘TIME’ )它的单位是否适合公认的时间单位 (TUNITn 是时间单位)。

例如,读取具有上述标题和时间坐标列的Chandra事件列表 time 作为 [1, 2] 将给予:

>>> from astropy.table import Table
>>> from astropy.time import Time, TimeDelta
>>> from astropy.utils.data import get_pkg_data_filename
>>> chandra_events = get_pkg_data_filename('data/chandra_time.fits',
...                                        package='astropy.io.fits.tests')
>>> native = Table.read(chandra_events, astropy_native=True)  
>>> native['time']  
<Time object: scale='tt' format='mjd' value=[57413.76033393 57413.76033393]>
>>> non_native = Table.read(chandra_events)
>>> # MJDREF  =  5.0814000000000E+04, TIMESYS = 'TT'
>>> ref_time = Time(non_native.meta['MJDREF'], format='mjd',
...                 scale=non_native.meta['TIMESYS'].lower())
>>> # TTYPE1  = 'time', TUNIT1 = 's'
>>> delta_time = TimeDelta(non_native['time'])
>>> all(ref_time + delta_time == native['time'])
True

默认情况下,FITS表列将作为标准列读取 Column 对象而不考虑FITS时间标准。

  • ISO 8601日期时间格式的字符串时间列

FITS使用iso8601的一个子集(它本身并不意味着一个特定的时间刻度)来表示几个与时间相关的关键字,例如DATE xxx。遵循FITS标准,其值必须以字符串形式写入以下内容 datetime 格式:

[+/-C]CCYY-MM-DD[Thh:mm:ss[.s...]]

时间坐标列可以用这个时间表示来构造。以下是ISO 8601的示例 datetime 设置时间列格式:

TIME
----
1999-01-01T00:00:00
1999-01-01T00:00:40
1999-01-01T00:01:06
.
.
.
1999-01-20T01:10:00

识别ISO 8601格式时间坐标列的标准如下:

使用时间坐标帧关键字标识时间列,如中所述 适合具有时间列的表格 . 一旦它被识别出来,它的数据类型就会被检查以确定它的表示格式。自ISO 8601 datetime 格式是时间的唯一字符串表示形式,具有字符串数据类型的时间坐标列将自动读取为 Time 对象与 format='fits' (“配合”表示符合ISO 8601格式)。

由于此格式不表示特定的时间刻度,因此它是使用标头中的时间刻度关键字确定的 (TCTYPTIMESYS )或者他们的违约。其他时间坐标信息也以同样的方式确定,使用时间坐标帧关键字。所有ISO 8601时间都是相对于全球公认的零点(0年对应于公元前1年),因此与参考时间关键字(MJDREF、JDREF或DATEREF)无关。因此,在处理ISO8601时间列时,这些关键字将被忽略。

注解

读取使文件符合时间坐标列 may 失败。 astropy 支持这些文件的大部分,但仍有一些FITS文件不符合标准的任何方面。如果您有这样的档案,请不要犹豫让我们知道(通过打开一个问题在 issue tracker

还有,读一篇专栏文章 TTYPEn = ‘TIME’ 作为 Time 如果 TUNITn 因为该列不是FITS识别的时间单位。

细节

在天文数据中,时间作为一个维度,在FITS文件中的表示是一个挑战。因此,该标准被扩展到严格描述 World Coordinate System 框架。参考 FITS WCS paper IV 有关详细信息。

允许 Time 因此,要在FITS表中写入时间坐标列的列需要以确保精度保持的方式存储时间值,并将相关元数据映射到相关的FITS关键字。

该标准规定,在二进制表中,可以使用双精度对 astropy 在这样一个表中,时间列被写成两个双精度的向量 (TFORMn = ‘2D’) (jd1, jd2) 在哪里? JD = jd1 + jd2 . 这将时间值复制到双倍精度,是“无损”版本,利用二进制表中提供的更高精度。请注意 jd1 总是半整数或整数,而 abs(jd2) < 1 . "往返 astropy -包含时间坐标列的writefits二进制表部分通过映射选定的元数据实现, scale 和单数 location 属于 Time ,对应关键字。请注意,在 Table 对象 meta 迪克特没有写出来,将会丢失。

实例

考虑以下时间列:

>>> t['a'] = Time([100.0, 200.0], scale='tt', format='mjd')  

FITS标准需要一个附加的转换层返回到所需的格式。时间列 t['a'] 将接受翻译 Astropy Time --> FITS --> Astropy Time 对应于格式转换 mjd --> (jd1, jd2) --> jd . 因此,从 (jd1, jd2) 需要一个完全符合FITS时间标准的软件实现。

考虑到这一点,通过选择将时间表示值存储为 format 的属性 Time column, instead of the (jd1, jd2) format, with no extra metadata in the header. This is the "lossy" version, but can help with portability. For the above example, the FITS column corresponding to t['a'] will then store [100.0 200.0] instead of [[ 2400100.5, 0. ], [ 2400200.5, 0. ]]. This is done by setting the Table serialization methods 对于写入时的时间列,如下例所示:

>>> from astropy.time import Time
>>> from astropy.table import Table
>>> from astropy.coordinates import EarthLocation
>>> t = Table()
>>> t['a'] = Time([100.0, 200.0], scale='tt', format='mjd')
>>> t.write('my_table.fits', overwrite=True,
...         serialize_method={Time: 'formatted_value'})
>>> tm = Table.read('my_table.fits')
>>> tm['a']
<Column name='a' dtype='float64' length=2>
100.0
200.0
>>> all(tm['a'] == t['a'].value)
True

默认情况下, serialize_method 对于时间列等于 'jd1_jd2' ,也就是说,时间列将完全精确地写入。

注解

这个 astropy Time 对象未精确映射到FITS时间标准。

  • FORMAT

    FITS格式只考虑三种格式:iso8601、JD和MJD。 astropy 时间允许许多其他格式,如 unixcxcsec 代表价值观。

    因此, format 不存储时间属性。从FITS读取后,用户必须设置 format 根据需要。

  • LOCATION

    在FITS标准中,时间坐标的参考位置是通过关键字表示的标量。但是,矢量化的参考位置或位置可以由 Green Bank Keyword Convention 这是一个注册的FITS大会。在 astropy 时间,位置可以是一个数组,可以广播到时间值。

    因此,矢量化 location 时间属性的存储和读取遵循此约定。

HDF5

从/到读/写 HDF5 文件支持 format='hdf5' (这需要 h5py 待安装)。但是 .hdf5 在写入文件时,文件扩展名是自动识别的,而HDF5文件在读入(使用文件的前几个字节来标识格式)时会自动识别(即使使用不同的扩展名),因此在大多数情况下,您不需要显式指定 format='hdf5' .

由于HDF5文件可以包含多个表,因此应该通过 path= 读写时的争论。

实例

读一个名为 data 从名为 observations.hdf5 ,您可以:

>>> t = Table.read('observations.hdf5', path='data')

要读取嵌套在HDF5文件中组中的表,可以执行以下操作:

>>> t = Table.read('observations.hdf5', path='group/data')

要将表写入新文件,还应指定路径:

>>> t.write('new_file.hdf5', path='updated_data')

也可以使用 append=True ::

>>> t.write('observations.hdf5', path='updated_data', append=True)

与其他格式一样 overwrite=True 参数支持重写现有文件。要在包含多个数据集的HDF5文件中仅覆盖一个表,请使用 both 这个 overwrite=Trueappend=True 争论。

最后,在写入HDF5文件时 compression= 参数可用于确保数据在磁盘上被压缩:

>>> t.write('new_file.hdf5', path='updated_data', compression=True)

元数据和Mixin列

astropy 表可以包含元数据,两者都在表中 meta 属性(这是任意键/值对的有序字典),以及列中,每个列都有属性 unitformatdescriptionmeta .

默认情况下,当向HDF5写入表时,代码将尝试在表中存储每个键/值对 meta 作为表数据集的HDF5属性。如果 meta 不是可以存储为HDF5属性的对象。此外,如果正在存储的表列为上面列出的任何列属性定义了值,则这些元数据将 not 并发出警告。

serialize_meta

要启用将所有表和列元数据存储到HDF5文件,请调用 write() 方法与 serialize_meta=True . 这将在一个单独的HDF5数据集中存储元数据,该数据集包含在同一个文件中,该文件名为 <path>.__table_column_meta__ . 在这里 path 参数是否在调用中提供 write() ::

>>> t.write('observations.hdf5', path='data', serialize_meta=True)

表元数据存储为字符串的数据集,方法是将元数据序列化为YAML中的 ECSV header format 定义。由于大多数常用语言都有YAML解析器,所以如果在非astropy应用程序中读取HDF5,那么可以轻松地访问和使用表元数据。

至于 astropy 3.0,通过指定 serialize_meta=True 还可以将包含 混合柱TimeSkyCoord 柱。

Pandas

astropy Table supports the ability to read or write tables using some of the I/O methods 可在 pandas. 因此,该接口为以下函数/方法提供了方便的包装:

格式名称

数据描述

读者

writer

pandas.csv

CSV

read_csv()

to_csv()

pandas.json

JSON

read_json()

to_json()

pandas.html

HTML

read_html()

to_html()

pandas.fwf

固定宽度

read_fwf()

笔记

在读或写表时,除了 format 文件名被传递给pandas,例如:

>>> t.write('data.csv', format='pandas.csv', sep=' ', header=False)
>>> t2 = Table.read('data.csv', format='pandas.csv', sep=' ', names=['a', 'b', 'c'])

JSViewer

提供表的交互式HTML导出,如 HTML 但使用 DataTables 库,允许以交互方式可视化HTML表(包括排序、搜索和分页列)。

例子

写表格 t 到新文件:

>>> t.write('new_table.html', format='jsviewer')

可以使用几个附加参数:

  • table_id :的HTML ID <table> 标记,默认为 'table{{id}}' 在哪里? id 是表对象的ID。

  • max_lines :最大行数。

  • table_class :HTML类添加到 <table> 标记,可用于自定义表的样式。

  • jskwargs公司 :传递给的其他参数 JSViewer .

  • css :CSS样式,默认为 astropy.table.jsviewer.DEFAULT_CSS .

  • htmldict公司 :传递给的其他参数 HTML .

VO表

从/到读/写 VO table 文件支持 format='votable' . 在大多数情况下,现有的VO表应该根据文件头自动标识出来,但是如果没有,或者写入磁盘,那么应该显式指定格式。

实例

如果一个VO表文件只包含一个表,那么可以使用以下命令读入它:

>>> t = Table.read('aj285677t3_votable.xml')

如果文件中存在多个表,则将引发错误,除非通过 table_id= 论点:

>>> t = Table.read('catalog.xml')
Traceback (most recent call last):
...
ValueError: Multiple tables found: table id should be set via the table_id= argument. The available tables are twomass, spitzer

>>> t = Table.read('catalog.xml', table_id='twomass')

要写入新文件,还应指定表的ID(除非 t.meta['ID'] 定义)::

>>> t.write('new_catalog.xml', table_id='updated_table', format='votable')

写作时 compression=True 参数可用于强制压缩磁盘上的数据,并且 overwrite=True 参数可用于覆盖现有文件。

表序列化方法

astropy 支持对表中列的写出(序列化)方式的细粒度控制。例如,如果要将ISO格式的时间列写入ECSV ASCII表文件,则可能需要将其作为一对JD1/JD2浮点值来实现完全分辨率(完美的“往返”),或者将其作为格式化的ISO日期字符串,以便其他应用程序可以轻松读取这些值。

序列化的默认方法取决于格式(FITS、ECSV、HDF5)。例如,HDF5是一种二进制格式,因此将时间对象存储为JD1/JD2是有意义的,而ECSV是一种平面ASCII格式,通常您希望以与时间对象相同的格式查看日期。默认值还反映了一种尝试,即尽量减少 astropy 版本。例如,在能够以JD1/JD2对写入之前的版本中,可以将时间列作为格式化字符串写入ECSV,因此ECSV当前的默认设置是以格式化字符串的形式写入。

具有可配置序列化方法的两个类是 Time and MaskedColumn. See the sections on Time DetailsMasked columns ,以获取更多信息。每种格式的默认值如下所示:

格式

时间

MaskedColumn

FITS

jd1_jd2

null_value

ECSV

formatted_value

null_value

HDF5

jd1_jd2

data_mask

YAML

jd2_jd2

---

实例

首先创建一个包含时间列和掩码列的表:

>>> import sys
>>> from astropy.time import Time
>>> from astropy.table import Table, MaskedColumn
>>> t = Table(masked=True)
>>> t['tm'] = Time(['2000-01-01', '2000-01-02'])
>>> t['mc1'] = MaskedColumn([1.0, 2.0], mask=[True, False])
>>> t['mc2'] = MaskedColumn([3.0, 4.0], mask=[False, True])
>>> t
<Table masked=True length=2>
           tm             mc1     mc2
         object         float64 float64
----------------------- ------- -------
2000-01-01 00:00:00.000      --     3.0
2000-01-02 00:00:00.000     2.0      --

现在指定要全部 Time 列编写为JD1/JD2和 mc1 列作为数据/掩码对写入并写入ECSV:

>>> serialize_method = {Time: 'jd1_jd2', 'mc1': 'data_mask'}
>>> t.write(sys.stdout, format='ascii.ecsv', serialize_method=serialize_method)
# %ECSV 0.9
 ...
# schema: astropy-2.0
 tm.jd1    tm.jd2  mc1  mc1.mask  mc2
2451544.0    0.5   1.0   True     3.0
2451546.0   -0.5   2.0   False     ""

(为清楚起见,增加了空格)

Notice that the tm column has been replaced by the tm.jd1 and tm.jd2 columns, and likewise a new column mc1.mask has appeared and it explicitly contains the mask values. When this table is read back with the ascii.ecsv reader then the original columns are reconstructed.

这个 serialize_method 参数可以用两种不同的方式设置:

  • 就像一根弦 data_mask . 然后,该值将应用于每一列,对于没有时间列的屏蔽表来说,这是一种方便的策略。

  • 作为一个 dict ,其中键可以是单个列名或类(如上面的示例所示),值是相应的序列化方法。