书写表格

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

这个 write() 函数提供了一种将数据表写入格式化ASCII表的方法。

实例

使用 write() 功能:

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

这个 values.dat 文件将包含:

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)  

输入数据格式

输入 table 参数 write() 可以是初始化时支持的任何值 Table 对象。详细记录在 构造表 节,包括创建具有列列表、列字典或 numpy 数组(结构化或同构)。

表或NumPy结构化数组

神经病 Table 物体或纽姆 structured array (或记录数组)可以作为 write() 功能。

例子

创建具有 numpy 结构化数组或现有表:

>>> from astropy.io import ascii
>>> from astropy.table import Table

>>> data = Table({'a': [1, 2, 3],
...               'b': [4.0, 5.0, 6.0]},
...              names=['a', 'b'])
>>> ascii.write(data)
a b
1 4.0
2 5.0
3 6.0

>>> data = np.array([(1, 2., 'Hello'), (2, 3., "World")],
...                 dtype=('i4,f4,a10'))
>>> ascii.write(data)
f0 f1 f2
1 2.0 Hello
2 3.0 World

产量 astropy.io.ascii.read 是一个 Table 或NumPy数组数据对象,它可以作为 write() 功能。

>>> data = ascii.read('data/daophot.dat', format='daophot')  
>>> ascii.write(data, 'space_delimited_table.dat')  

名单 list 物体

Python列表 list 对象(或任何iterable对象)都可以用作输入:

>>> x = [1, 2, 3]
>>> y = [4, 5.2, 6.1]
>>> z = ['hello', 'world', '!!!']
>>> data = [x, y, z]

>>> ascii.write(data)
col0 col1 col2
1 4.0 hello
2 5.2 world
3 6.1 !!!

这个 data 对象不包含有关列名的信息,因此 Table 自动选择了它们。要指定名称,请提供 names 关键字参数。此示例还显示了从输出中排除一列:

>>> ascii.write(data, names=['x', 'y', 'z'], exclude_names=['y'])
x z
1 hello
2 world
3 !!!

dict 属于 list 物体

包含iterable对象的字典可以用作 write() . 每个dict键作为列名,而值必须是包含相应列值的iterable对象。

由于Python字典没有排序,因此输出列的顺序将不可预测,除非 names 提供了参数。

例子

dict 属于 list 物体::

>>> data = {'x': [1, 2, 3],
...         'y': [4, 5.2, 6.1],
...         'z': ['hello', 'world', '!!!']}
>>> ascii.write(data, names=['x', 'y', 'z'])
x y z
1 4.0 hello
2 5.2 world
3 6.1 !!!

参数用于 write()

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

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

输出 :输出说明符

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

  • 文件名(字符串)

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

桌子 :输入表

初始化时支持的任何值 Table 对象(参见 构造表

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

指定要写入的ASCII表的格式,例如基本字符分隔表、固定格式表或与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)},
姓名 :每个数据列对应的名称列表

为每个数据列定义完整的名称列表。这将覆盖从数据表中确定的名称(如果可用)。如果未提供,则使用数据表中的名称或自动生成的名称。

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 禁用此行为。

writer :Writer类( 贬低 赞成 formatWriter类(

指定要写入的ASCII表的顶层格式,例如基本字符分隔表、固定格式表或CDS兼容表等。此参数的值必须是Writer类。对于基本用法,这意味着内置 扩展读取器类 . 请注意,Reader类和Writer类是同义词;换句话说,Reader类也可以写,但由于历史原因,它们通常被称为Reader类。

ECSV格式

这个 Enhanced Character-Separated Values (ECSV) format 可以用来写字 astropy TableQTable 将数据集转换为纯文本数据文件,然后在不丢失信息的情况下读回表。该格式通过使用YAML编码的数据结构处理列规范和表元数据序列化的关键问题。实际的表格数据以标准字符分隔值(CSV)格式存储,从而与各种非专用CSV表读取器兼容。

混合柱

astropy 2.0不仅可以存储标准 Column 对象ECSV,但也包括以下内容 混合柱

通常,mixin列可能包含多个数据组件以及超出标准的对象属性 Columnformatdescription . 存储这样的mixin列是通过将mixin列替换为表示底层数据组件的列,然后插入元数据来通知读者如何重建原始列。例如,a SkyCoord 混合柱输入 'spherical' 表示将具有数据属性 radecdistance ,以及对象属性,如 representation_typeframe .

例子

创建具有 SkyCoord column can be accomplished with a mixin column, which is supported by ECSV . 要存储mixin列:

>>> from astropy.io import ascii
>>> from astropy.coordinates import SkyCoord
>>> import astropy.units as u
>>> from astropy.time import Time
>>> from astropy.table import QTable, Column

>>> sc = SkyCoord(ra=[1,2]*u.deg, dec=[3,4]*u.deg, distance=[5,6]*u.m,
...               frame='fk4', obstime=Time('2000:001'))
>>> sc.info.description = 'flying circus'
>>> c = Column([1,2])
>>> q = [1,2]*u.m
>>> q.info.format = '.2f'
>>> t = QTable([c, q, sc], names=['c', 'q', 'sc'])

>>> ascii.write(t, format='ecsv')   
# %ECSV 0.9
# ---
# datatype:
# - {name: c, datatype: int64}
# - {name: q, unit: m, datatype: float64}
# - {name: sc.ra, unit: deg, datatype: float64}
# - {name: sc.dec, unit: deg, datatype: float64}
# - {name: sc.distance, unit: m, datatype: float64}
# meta: !!omap
# - __serialized_columns__:
#     q:
#       __class__: astropy.units.quantity.Quantity
#       value: !astropy.table.SerializedColumn {name: q}
#     sc:
#       __class__: astropy.coordinates.sky_coordinate.SkyCoord
#       __info__: {description: flying circus}
#       dec: !astropy.table.SerializedColumn
#         __class__: astropy.coordinates.angles.Latitude
#         value: !astropy.table.SerializedColumn {name: sc.dec}
#       distance: !astropy.table.SerializedColumn
#         __class__: astropy.coordinates.distances.Distance
#         value: !astropy.table.SerializedColumn {name: sc.distance}
#       equinox: !astropy.time.Time {format: byear_str, in_subfmt: '*', jd1: 2400000.5,
#         jd2: 33281.92345905, out_subfmt: '*', precision: 3, scale: tai}
#       frame: fk4
#       obstime: !astropy.time.Time {format: yday, in_subfmt: '*', jd1: 2451544.5, jd2: 0.0,
#         out_subfmt: '*', precision: 3, scale: utc}
#       ra: !astropy.table.SerializedColumn
#         __class__: astropy.coordinates.angles.Longitude
#         value: !astropy.table.SerializedColumn {name: sc.ra}
#         wrap_angle: !astropy.coordinates.Angle
#           unit: !astropy.units.Unit {unit: deg}
#           value: 360.0
#       representation: spherical
# schema: astropy-2.0
c q sc.ra sc.dec sc.distance
1 1.0 1.0 3.0 5.0
2 2.0 2.0 4.0 6.0

这个 '__class__' 关键字提供完全限定的类名,并且必须是指定允许的 astropy 类。没有添加用户指定的允许类的选项。这个 '__info__' 关键字包含标准值 Columndescriptionformat ,对于由多个序列化列表示的任何mixin列。

遮罩柱

默认情况下,ECSV格式在输出表中使用空(零长度)字符串来表示 MaskedColumn 柱。在某些情况下,这可能不够:

  • 包含空字符串(零长度)作为有效数据的字符串列。

  • 必须存储屏蔽数据值,以便以后可以对这些值进行解密。

在这种情况下,有一种可用的机制来指定完整数据和掩码本身应该作为列写入输出表中,如下例所示。有关详细信息,请参阅 表序列化方法 .

例子

要指定将完整数据和掩码本身作为列写入输出表中,请执行以下操作:

>>> from astropy.table.table_helpers import simple_table
>>> t = simple_table(masked=True)
>>> t['c'][0] = ""  # Valid empty string in data
>>> t
<Table masked=True length=3>
  a      b     c
int64 float64 str1
----- ------- ----
   --     1.0
    2     2.0   --
    3      --    e

现在我们告诉ECSV writer为字符串列输出单独的数据和掩码列 'c' ::

>>> t['c'].info.serialize_method['ecsv'] = 'data_mask'

当它被写出来时,请注意,输出显示了 'c' 立柱(包括面罩 'd' 值)和新列 'c.masked' . 它还存储元数据,告诉ECSV读取器解释 'c''c.masked' 列作为一个组件 MaskedColumn 对象:

>>> ascii.write(t, format='ecsv')
# %ECSV 0.9
# ---
# datatype:
# - {name: a, datatype: int64}
# - {name: b, datatype: float64}
# - {name: c, datatype: string}
# - {name: c.mask, datatype: bool}
# meta: !!omap
# - __serialized_columns__:
#     c:
#       __class__: astropy.table.column.MaskedColumn
#       data: !astropy.table.SerializedColumn {name: c}
#       mask: !astropy.table.SerializedColumn {name: c.mask}
# schema: astropy-2.0
a b c c.mask
"" 1.0 "" False
2 2.0 d True
3 "" e False

当您读回此内容时,列第一行中的空字符串(零长度) 'c' 将被保存。您还可以使用表的统一I/O接口将所有列作为数据和掩码对写出 serialize_method 关键字参数:

>>> t.write('out.ecsv', format='ascii.ecsv', serialize_method='data_mask')  

在这种情况下,当您读回文件时,所有的数据值(包括原始表中“掩码下”的值)都将完全恢复。