书写表格#

astropy.io.ascii 能够使用与读取表相同的类结构和基本用户界面将文本表写入文件或类似文件的对象。

上的帮助 write() 函数参数是交互式的,如本例所示:

>>> from astropy.io import ascii
>>> ascii.write.help()  # Common help for all formats
>>> ascii.write.help("html")  # Common help plus "html" format-specific args

write() 函数提供了一种将数据表编写为格式化文本表的方法。

实例#

要使用编写格式化文本表 write() 功能::

>>> import numpy as np
>>> from astropy.io import ascii
>>> from astropy.table import Table
>>> data = Table()
>>> data['x'] = np.array([1, 2, 3], dtype=np.int32)
>>> data['y'] = data['x'] ** 2
>>> ascii.write(data, 'values.dat', overwrite=True)

这个 values.dat 文件将包含:

x y
1 1
2 4
3 9

也可以并鼓励使用中的写入功能 astropy.io.ascii 通过中的更高级别接口 Data Tables 包(请参见 高级统一文件I/O 以了解更多详细信息)。例如::

>>> data.write('values.dat', format='ascii', overwrite=True)

对于表格的可重复性更强的文本版本,我们建议使用 ECSV格式 .这将所有表元数据(特别是列类型和单位)存储到开头的注释部分,同时仍然保持与大多数普通CSV阅读器的兼容性。它还允许存储更丰富的数据,如 SkyCoord 或多维或可变长度列。对于我们的简单例子::

>>> data.write('values.ecsv', overwrite=True)

这个 .ecsv 扩展被识别并隐含使用ECSV(相当于 format='ascii.ecsv' )。这个 values.ecsv 然后,文件将包含::

# %ECSV 1.0
# ---
# datatype:
# - {name: x, datatype: int32}
# - {name: y, datatype: int32}
# schema: astropy-2.0
x y
1 1
2 4
3 9

大部分输入表 支持的格式 阅读也可用于写作。这为写作的格式提供了很大的灵活性。下面的示例将数据作为LaTeX表写入,使用选项将输出发送到 sys.stdout 而不是文件:

>>> ascii.write(data, format='latex')
\begin{table}
\begin{tabular}{cc}
x & y \\
1 & 1 \\
2 & 4 \\
3 & 9 \\
\end{tabular}
\end{table}

还有一个用于编写简单格式的更快的Cython引擎,对于这些格式,默认情况下是启用的(请参见 快速ASCII I/O ). 要停用此引擎,请使用参数 fast_writer ::

>>> ascii.write(data, 'values.csv', format='csv', fast_writer=False)

备注

对于大多数支持的格式,您可以编写一个屏蔽表,然后将其读回,而不会丢失有关屏蔽表项的信息。这是通过使用一个空白字符串条目来指示一个屏蔽(丢失)值来实现的。见 错误或缺少值 有关详细信息,请参阅。

参数用于 write()#

这个 write() 函数接受许多指定详细输出表格式的参数。每个 支持的格式 由相应的Writer类处理,该类可以定义不同的默认值,因此下面的描述有时会提到“典型”默认值。这是指 Basic writer和其他类似的writer类。

一些输出格式编写器类(例如。, LatexAASTex )接受可以进一步自定义输出的其他关键字。有关详细信息,请参阅这些类的文档。

输出 :输出说明符

有两种方法可以指定写入操作的输出:

  • 文件名(字符串)

  • 类似文件的对象(from open()、StringIO等)

桌子 :输入表

任何支持初始化 Table 对象(请参见 构造表 )。这包括具有列列表的表、列的字典或来自 numpy 数组(结构化或同构)。

格式 :输出格式(default='basic')

这指定要编写的文本表的格式,例如基本字符分隔的表、固定格式表或CDS兼容表等。此参数的值必须是 支持的格式 .

定界符 :列分隔符字符串

用于分隔字段的单字符字符串,通常默认为空格字符。其他常用值可能是“,”或“|”或“\t”。

评论 :定义输出表中注释行开头的字符串

对于 Basic 写入此默认值为“#”。哪些注释是编写的,以及如何取决于所选格式。注释定义为输入表中字符串的列表 meta['comments'] 元素。给定的元数据中的注释 Table 通常写在头之前,但是 CommentedHeader 在注释标头之后写入表注释。写入注释,设置为禁用 comment=False .

格式 :数据类型转换器的dict

对于每个键(列名),使用给定值将列数据转换为字符串。如果format值是类似字符串的,那么它将用作Python格式语句(例如,“%0.2f”%value)。如果它是一个可调用函数,则该函数将使用包含要转换的列值的单个参数来调用。例子::

astropy.io.ascii.write(table, sys.stdout, formats={'XCENTER': '%12.1f',
                                             'YCENTER': lambda x: round(x, 1)},
names :输出列名列表

定义要为数据表写入的输出列名的完整列表,覆盖现有列名。

include_names :要包含在输出中的名称列表

从数据表或 names 参数,选择此列表中仅输出列。如果未提供,则包括所有名称。

exclude_names :要从输出中排除的名称列表

从输出列列表中排除这些名称。这是适用的 之后 这个 include_names 过滤。如果未指定,则不排除任何列。

fill_values :填充值说明符列表

这可以用来填充表中缺少的值或用特殊含义替换值。

错误或缺少值 有关语法的详细信息。语法与读取表时几乎相同。有一个特殊的价值 astropy.io.ascii.masked 用于表示“为屏蔽表中的所有屏蔽值输出此字符串”(默认为使用空字符串) "" ):

>>> import sys
>>> from astropy.table import Table, Column, MaskedColumn
>>> from astropy.io import ascii
>>> t = Table([(1, 2), (3, 4)], names=('a', 'b'), masked=True)
>>> t['a'].mask = [True, False]
>>> ascii.write(t, sys.stdout)
a b
"" 3
2 4
>>> ascii.write(t, sys.stdout, fill_values=[(ascii.masked, 'N/A')])
a b
N/A 3
2 4

请注意,在编写表时,在替换任何值之前,所有值都将转换为字符串。因为 fill_values 只替换与规范完全匹配的单元格,您需要为每个值提供字符串表示(去掉空白)。例如,在以下命令中 -99 我们需要用逗号替换后面的两个数字 -99.00 而不是 -99 ::

>>> t = Table([(-99, 2), (3, 4)], names=('a', 'b'))
>>> ascii.write(t, sys.stdout, fill_values = [('-99.00', 'no data')],
...             formats={'a': '%4.2f'})
a b
"no data" 3
2.00 4

类似地,如果替换具有固定长度格式的列中的值(例如。, 'f4.2' ),则要替换的字符串必须具有相同的字符数。在上面的例子中, fill_values=[(' nan',' N/A')] 会有用的。

fill_include_names :受影响的列名列表 fill_values

如果未提供,则 fill_values 可以影响所有列。

fill_exclude_names :不受影响的列名列表 fill_values

如果未提供,则 fill_values 可以影响所有列。

fast_writer :是否使用快速Cython writer

如果此参数为 None (默认情况下), write() 将尝试使用速度更快的写入程序(如中所述 快速ASCII I/O )如果可能的话。指定 fast_writer=False 禁用此行为。

机器可读的表格格式#

美国天文学会期刊 Machine-Readable Table (MRT) 格式由带有表描述标头和表数据本身的单个文件组成。捷运类似于 CDS 格式规范,但在表的描述部分有所不同,缺少单独的 ReadMe 文件。Astropy不支持以CDS格式写入。

这个 Mrt 写入器支持将表格写入为MRT格式。

备注

表的元数据,列除外 unitnamedescription 不会写入输出文件中。标题、作者和表名字段的占位符将放入输出文件中,并可在写入后进行编辑。

实例#

该命令 ascii.write(format='mrt') 写了一篇 astropy Table 转换为MRT格式。横断面分隔符 ---=== 用于将表划分为不同的部分,最后一部分始终是实际数据。

按照MRT标准的要求,对于具有 unit 属性未设置为 None 中,单位名称列在该列的逐字节描述中。当列不包含任何单位时, --- 而不是放在。一个 ? 以逐字节的形式添加到列描述的前缀 Masked 一个或多个具有空值的列,表明它们是空值。

下面的示例初始化表,其中的列具有 unit 属性,并具有屏蔽值。

>>> from astropy.io import ascii
>>> from astropy.table import Table, Column, MaskedColumn
>>> from astropy import units as u
>>> table = Table()
>>> table['Name'] = ['ASASSN-15lh', 'ASASSN-14li']
>>> # MRT Standard requires all quantities in SI units.
>>> temperature = [0.0334, 0.297] * u.K
>>> table['Temperature'] = temperature.to(u.keV, equivalencies=u.temperature_energy())
>>> table['nH'] = Column([0.025, 0.0188], unit=u.Unit(10**22))
>>> table['Flux'] = ([2.044 * 10**-11] * u.erg * u.cm**-2).to(u.Jy * u.Unit(10**12))
>>> table['Flux'] = MaskedColumn(table['Flux'], mask=[True, False])
>>> table['magnitude'] = [u.Magnitude(25), u.Magnitude(-9)]

请注意,对于包含 TimeTimeDelta 和相关值时,编写器不会进行任何内部转换或修改。这些列应转换为常规列,使用适当的 unitname 属性,然后再写入表。因此::

>>> from astropy.time import Time, TimeDelta
>>> from astropy.timeseries import TimeSeries
>>> ts = TimeSeries(time_start=Time('2019-01-01'), time_delta=2*u.day, n_samples=1)
>>> table['Obs'] = Column(ts.time.decimalyear, description='Time of Observation')
>>> table['Cadence'] = Column(TimeDelta(100.0, format='sec').datetime.seconds,
...                           unit=u.s)

符合以下条件的列 SkyCoord 具有作为此类对象的值的对象或列被识别为此类对象,并且对它们使用一些预定义的标签和描述。坐标列具有 SphericalRepresentation 还被细分为它们的坐标分量列。具有以下特征的陈述 ra and dec components are divided into their hour-min-sec and deg-arcmin-arcsec components respectively. Whereas columns with SkyCoord objects in the Galactic or any of the Ecliptic frames are divided into their latitude(ELAT/GLAT )和经度分量 (ELON /``GLAT`))。原始表仍可访问,而文件是从表的修改副本写入的。新的坐标分量列将附加到表格的末尾。

需要注意的是,纬度、经度和秒(弧线)列的默认精度设置为小数点后的默认数字12、10和9位 degsecarcsec 值。该缺省值设置为匹配相对于原始的1e-15的机器精度 SkyCoord 这些专栏是从。与所有其他列一样,可以通过传递 formats 关键字设置为 write 函数或通过设置 format 属性(后者仅适用于未分解的列)。若要自定义有效位数,因此应在 formats 英汉词典 output 列名,如 formats={'RAs': '07.4f', 'DEs': '06.3f'}formats={'GLAT': '+10.6f', 'GLON': '9.6f'} 毫分之秒的精度。请注意,建议使用以秒为前导零并包含纬度符号的形式,以获得更好的一致性和可读性。

下面的代码说明了上面的情况。

>>> from astropy.coordinates import SkyCoord
>>> table['coord'] = [SkyCoord.from_name('ASASSN-15lh'),
...                   SkyCoord.from_name('ASASSN-14li')]
>>> table.write('coord_cols.dat', format='ascii.mrt')
>>> table['coord'] = table['coord'].geocentrictrueecliptic
>>> table['Temperature'].format = '.5E' # Set default column format.
>>> table.write('ecliptic_cols.dat', format='ascii.mrt')

在执行后, coords_cols.dat 将是::

Title:
Authors:
Table:
================================================================================
Byte-by-byte Description of file: table.dat
--------------------------------------------------------------------------------
 Bytes Format Units  Label     Explanations
--------------------------------------------------------------------------------
 1-11  A11     ---    Name        Description of Name
13-23  E11.6   keV    Temperature [0.0/0.01] Description of Temperature
25-30  F6.4    10+22  nH          [0.01/0.03] Description of nH
32-36  F5.3   10+12Jy Flux        ? Description of Flux
38-42  E5.1    mag    magnitude   [0.0/3981.08] Description of magnitude
44-49  F6.1    ---    Obs         [2019.0/2019.0] Time of Observation
51-53  I3      s      Cadence     [100] Description of Cadence
55-56  I2     h      RAh           Right Ascension (hour)
58-59  I2     min    RAm           Right Ascension (minute)
61-73  F13.10 s      RAs           Right Ascension (second)
   75  A1     ---    DE-           Sign of Declination
76-77  I2     deg    DEd           Declination (degree)
79-80  I2     arcmin DEm           Declination (arcmin)
82-93  F12.9  arcsec DEs           Declination (arcsec)
--------------------------------------------------------------------------------
Notes:
--------------------------------------------------------------------------------
ASASSN-15lh 2.87819e-09 0.0250       1e-10 2019.0 100 22 02 15.4500000000 -61 39 34.599996000
ASASSN-14li 2.55935e-08 0.0188 2.044 4e+03 2019.0 100 12 48 15.2244072000 +17 46 26.496624000

还有那份文件 ecliptic_cols.dat 将如下所示::

Title:
Authors:
Table:
================================================================================
Byte-by-byte Description of file: table.dat
--------------------------------------------------------------------------------
 Bytes Format Units  Label     Explanations
--------------------------------------------------------------------------------
 1- 11  A11     ---    Name        Description of Name
13- 23  E11.6   keV    Temperature [0.0/0.01] Description of Temperature
25- 30  F6.4    10+22  nH          [0.01/0.03] Description of nH
32- 36  F5.3   10+12Jy Flux        ? Description of Flux
38- 42  E5.1    mag    magnitude   [0.0/3981.08] Description of magnitude
44- 49  F6.1    ---    Obs         [2019.0/2019.0] Time of Observation
51- 53  I3      s      Cadence     [100] Description of Cadence
55- 70  F16.12  deg    ELON        Ecliptic Longitude (geocentrictrueecliptic)
72- 87  F16.12  deg    ELAT        Ecliptic Latitude (geocentrictrueecliptic)
--------------------------------------------------------------------------------
Notes:
--------------------------------------------------------------------------------
ASASSN-15lh 2.87819e-09 0.0250       1e-10 2019.0 100 306.224208650096 -45.621789850825
ASASSN-14li 2.55935e-08 0.0188 2.044 4e+03 2019.0 100 183.754980099243  21.051410763027

最后,MRT对列有一些特定的命名约定 (https://journals.aas.org/mrt-labels/#reflab) 。例如,如果某列包含名为的列中数据的平均误差 label ,则应将此列命名为 e_label 。MRT编写器不能强制执行这些类型的相对列命名,因为它不知道列数据的含义,因此无法弄清楚列之间的关系。因此,它由用户决定是否使用 Table.rename_columns 在将表写入MRT格式之前适当地重命名任何列。下面的示例显示了类似的情况,使用选项将输出发送到 sys.stdout 不是文件::

>>> table['error'] = [1e4, 450] * u.Jy  # Error in the Flux values.
>>> outtab = table.copy()  # So that changes don't affect the original table.
>>> outtab.rename_column('error', 'e_Flux')
>>> # re-order so that related columns are placed next to each other.
>>> outtab = outtab['Name', 'Obs', 'coord', 'Cadence', 'nH', 'magnitude',
...                 'Temperature', 'Flux', 'e_Flux']

>>> ascii.write(outtab, format='mrt')
Title:
Authors:
Table:
================================================================================
Byte-by-byte Description of file: table.dat
--------------------------------------------------------------------------------
 Bytes Format Units  Label     Explanations
--------------------------------------------------------------------------------
 1- 11  A11     ---    Name        Description of Name
13- 18  F6.1    ---    Obs         [2019.0/2019.0] Time of Observation
20- 22  I3      s      Cadence     [100] Description of Cadence
24- 29  F6.4    10+22  nH          [0.01/0.03] Description of nH
31- 35  E5.1    mag    magnitude   [0.0/3981.08] Description of magnitude
37- 47  E11.6   keV    Temperature [0.0/0.01] Description of Temperature
49- 53  F5.3   10+12Jy Flux        ? Description of Flux
55- 61  F7.1    Jy     e_Flux      [450.0/10000.0] Description of e_Flux
63- 78  F16.12  deg    ELON        Ecliptic Longitude (geocentrictrueecliptic)
80- 95  F16.12  deg    ELAT        Ecliptic Latitude (geocentrictrueecliptic)
--------------------------------------------------------------------------------
Notes:
--------------------------------------------------------------------------------
ASASSN-15lh 2019.0 100 0.0250 1e-10 2.87819e-09       10000.0 306.224208650096 -45.621789850825
ASASSN-14li 2019.0 100 0.0188 4e+03 2.55935e-08 2.044   450.0 183.754980099243  21.051410763027

注意

MRT编写器当前支持在中自动写入单个坐标列 Tables 。对于具有多个给定类型的坐标列(如赤道、银河或黄道)的表格,只有第一个找到的坐标列将被分解为其组成部分列,其余相同类型的坐标列将被转换为字符串列。因此,用户应该注意处理附加的坐标列(例如,通过将它们转换为唯一的 float -值列),然后使用 SkyCoord 方法:研究方法。