固定宽度画廊#
固定宽度表格是指表格中每一行的每一列宽度相同的表格。这通常用于使表易于人类或Fortran代码阅读。它还减少了引用和特殊字符的问题,例如:
Col1 Col2 Col3 Col4
---- --------- ---- ----
1.2 "hello" 1 a
2.4 's worlds 2 2
固定宽度表格的格式有许多常见的变化 astropy.io.ascii
会读会写。最显著的区别是是否没有标题行 (FixedWidthNoHeader
),一条标题行 (FixedWidth
),或两条标题行 (FixedWidthTwoLine
). 接下来,定界符字符也有变化,比如定界符是出现在任一端(“bookends”),还是在定界符周围有填充。
详细信息可以在类API文档中找到,但是理解所有选项及其交互作用的最简单方法是通过示例。
阅读#
固定宽度#
Nice, typical, fixed-format table: ::
>>> from astropy.io import ascii
>>> table = """
... # comment (with blank line above)
... | Col1 | Col2 |
... | 1.2 | "hello" |
... | 2.4 |'s worlds|
... """
>>> ascii.read(table, format='fixed_width')
<Table length=2>
Col1 Col2
float64 str9
------- ---------
1.2 "hello"
2.4 's worlds
Typical fixed-format table with col names provided: ::
>>> table = """
... # comment (with blank line above)
... | Col1 | Col2 |
... | 1.2 | "hello" |
... | 2.4 |'s worlds|
... """
>>> ascii.read(table, format='fixed_width', names=['name1', 'name2'])
<Table length=2>
name1 name2
float64 str9
------- ---------
1.2 "hello"
2.4 's worlds
数据值被列范围截短的怪异输入表: ::
>>> table = """
... Col1 | Col2 |
... 1.2 "hello"
... 2.4 sdf's worlds
... """
>>> ascii.read(table, format='fixed_width')
<Table length=2>
Col1 Col2
float64 str7
------- -------
1.2 "hel
2.4 df's wo
带双分隔符的表: ::
>>> table = """
... || Name || Phone || TCP||
... | John | 555-1234 |192.168.1.10X|
... | Mary | 555-2134 |192.168.1.12X|
... | Bob | 555-4527 | 192.168.1.9X|
... """
>>> ascii.read(table, format='fixed_width')
<Table length=3>
Name Phone TCP
str4 str8 str12
---- -------- ------------
John 555-1234 192.168.1.10
Mary 555-2134 192.168.1.12
Bob 555-4527 192.168.1.9
带空格分隔符的表: ::
>>> table = """
... Name --Phone- ----TCP-----
... John 555-1234 192.168.1.10
... Mary 555-2134 192.168.1.12
... Bob 555-4527 192.168.1.9
... """
>>> ascii.read(table, format='fixed_width', delimiter=' ')
<Table length=3>
Name --Phone- ----TCP-----
str4 str8 str12
---- -------- ------------
John 555-1234 192.168.1.10
Mary 555-2134 192.168.1.12
Bob 555-4527 192.168.1.9
Table with no header row and auto-column naming:
使用 header_start
和 data_start
表示没有标题行的关键字。:
>>> table = """
... | John | 555-1234 |192.168.1.10|
... | Mary | 555-2134 |192.168.1.12|
... | Bob | 555-4527 | 192.168.1.9|
... """
>>> ascii.read(table, format='fixed_width',
... header_start=None, data_start=0)
<Table length=3>
col1 col2 col3
str4 str8 str12
---- -------- ------------
John 555-1234 192.168.1.10
Mary 555-2134 192.168.1.12
Bob 555-4527 192.168.1.9
没有标题行且提供了列名称的表:
第二排和第三排在最后一个“|”之后也有悬挂空间。使用header_start和data_start关键字指示没有标题行。:
>>> table = ["| John | 555-1234 |192.168.1.10|",
... "| Mary | 555-2134 |192.168.1.12| ",
... "| Bob | 555-4527 | 192.168.1.9| "]
>>> ascii.read(table, format='fixed_width',
... header_start=None, data_start=0,
... names=('Name', 'Phone', 'TCP'))
<Table length=3>
Name Phone TCP
str4 str8 str12
---- -------- ------------
John 555-1234 192.168.1.10
Mary 555-2134 192.168.1.12
Bob 555-4527 192.168.1.9
固定宽度无页眉#
Table with no header row and auto-column naming. Use the ``fixed_width_no_header`` format for convenience: ::
>>> table = """
... | John | 555-1234 |192.168.1.10|
... | Mary | 555-2134 |192.168.1.12|
... | Bob | 555-4527 | 192.168.1.9|
... """
>>> ascii.read(table, format='fixed_width_no_header')
<Table length=3>
col1 col2 col3
str4 str8 str12
---- -------- ------------
John 555-1234 192.168.1.10
Mary 555-2134 192.168.1.12
Bob 555-4527 192.168.1.9
没有指定列起始值和结束值的分隔符的表:
这使用col_start和col_ends关键字。请注意,col_ends值包含在内,因此0到5的位置范围将选择前6个字符。:
>>> table = """
... # 5 9 17 18 28 <== Column start / end indexes
... # | | || | <== Column separation positions
... John 555- 1234 192.168.1.10
... Mary 555- 2134 192.168.1.12
... Bob 555- 4527 192.168.1.9
... """
>>> ascii.read(table, format='fixed_width_no_header',
... names=('Name', 'Phone', 'TCP'),
... col_starts=(0, 9, 18),
... col_ends=(5, 17, 28),
... )
<Table length=3>
Name Phone TCP
str4 str9 str10
---- --------- ----------
John 555- 1234 192.168.1.
Mary 555- 2134 192.168.1.
Bob 555- 4527 192.168.1
没有分隔符的表,只指定了列的起始值或结束值:
如果只给出col_starts关键字,则假定每列在下一列开始处结束,而最后一列在与最长数据行相同的位置结束。
相反,如果只给出col_neuends关键字,则假定第一列从零开始,每个连续列紧跟在前一列之后。
下面的两个例子读同一个表并产生相同的结果。:
>>> table = """
... #1 9 19 <== Column start indexes
... #| | | <== Column start positions
... #<------><--------><-------------> <== Inferred column positions
... John 555- 1234 192.168.1.10
... Mary 555- 2134 192.168.1.123
... Bob 555- 4527 192.168.1.9
... Bill 555-9875 192.255.255.255
... """
>>> ascii.read(table,
... format='fixed_width_no_header',
... names=('Name', 'Phone', 'TCP'),
... col_starts=(1, 9, 19),
... )
<Table length=4>
Name Phone TCP
str4 str9 str15
---- --------- ---------------
John 555- 1234 192.168.1.10
Mary 555- 2134 192.168.1.123
Bob 555- 4527 192.168.1.9
Bill 555-9875 192.255.255.255
>>> ascii.read(table,
... format='fixed_width_no_header',
... names=('Name', 'Phone', 'TCP'),
... col_ends=(8, 18, 32),
... )
<Table length=4>
Name Phone TCP
str4 str9 str14
---- --------- --------------
John 555- 1234 192.168.1.10
Mary 555- 2134 192.168.1.123
Bob 555- 4527 192.168.1.9
Bill 555-9875 192.255.255.25
固定宽度双线#
Typical fixed-format table with two header lines with some cruft: ::
>>> table = """
... Col1 Col2
... ---- ---------
... 1.2xx"hello"
... 2.4 's worlds
... """
>>> ascii.read(table, format='fixed_width_two_line')
<Table length=2>
Col1 Col2
float64 str9
------- ---------
1.2 "hello"
2.4 's worlds
ReconstructedText表: ::
>>> table = """
... ======= ===========
... Col1 Col2
... ======= ===========
... 1.2 "hello"
... 2.4 's worlds
... ======= ===========
... """
>>> ascii.read(table, format='fixed_width_two_line',
... header_start=1, position_line=2, data_end=-1)
<Table length=2>
Col1 Col2
float64 str9
------- ---------
1.2 "hello"
2.4 's worlds
为人类和测试设计的文本表,标题行前面有位置行: ::
>>> table = """
... +------+----------+
... | Col1 | Col2 |
... +------|----------+
... | 1.2 | "hello" |
... | 2.4 | 's worlds|
... +------+----------+
... """
>>> ascii.read(table, format='fixed_width_two_line', delimiter='+',
... header_start=1, position_line=0, data_start=3, data_end=-1)
<Table length=2>
Col1 Col2
float64 str9
------- ---------
1.2 "hello"
2.4 's worlds
写作#
固定宽度#
Define input values ``dat`` for all write examples: ::
>>> table = """
... | Col1 | Col2 | Col3 | Col4 |
... | 1.2 | "hello" | 1 | a |
... | 2.4 | 's worlds | 2 | 2 |
... """
>>> dat = ascii.read(table, format='fixed_width')
Write a table as a normal fixed-width table: ::
>>> ascii.write(dat, format='fixed_width')
| Col1 | Col2 | Col3 | Col4 |
| 1.2 | "hello" | 1 | a |
| 2.4 | 's worlds | 2 | 2 |
Write a table as a fixed-width table with no padding: ::
>>> ascii.write(dat, format='fixed_width', delimiter_pad=None)
|Col1| Col2|Col3|Col4|
| 1.2| "hello"| 1| a|
| 2.4|'s worlds| 2| 2|
Write a table as a fixed-width table with no bookend: ::
>>> ascii.write(dat, format='fixed_width', bookend=False)
Col1 | Col2 | Col3 | Col4
1.2 | "hello" | 1 | a
2.4 | 's worlds | 2 | 2
Write a table as a fixed-width table with no delimiter: ::
>>> ascii.write(dat, format='fixed_width', bookend=False, delimiter=None)
Col1 Col2 Col3 Col4
1.2 "hello" 1 a
2.4 's worlds 2 2
Write a table as a fixed-width table with no delimiter and formatting: ::
>>> ascii.write(dat, format='fixed_width',
... formats={'Col1': '%-8.3f', 'Col2': '%-15s'})
| Col1 | Col2 | Col3 | Col4 |
| 1.200 | "hello" | 1 | a |
| 2.400 | 's worlds | 2 | 2 |
固定宽度无页眉#
Write a table as a normal fixed-width table: ::
>>> ascii.write(dat, format='fixed_width_no_header')
| 1.2 | "hello" | 1 | a |
| 2.4 | 's worlds | 2 | 2 |
Write a table as a fixed-width table with no padding: ::
>>> ascii.write(dat, format='fixed_width_no_header', delimiter_pad=None)
|1.2| "hello"|1|a|
|2.4|'s worlds|2|2|
Write a table as a fixed-width table with no bookend: ::
>>> ascii.write(dat, format='fixed_width_no_header', bookend=False)
1.2 | "hello" | 1 | a
2.4 | 's worlds | 2 | 2
Write a table as a fixed-width table with no delimiter: ::
>>> ascii.write(dat, format='fixed_width_no_header', bookend=False,
... delimiter=None)
1.2 "hello" 1 a
2.4 's worlds 2 2
固定宽度双线#
Write a table as a normal fixed-width table: ::
>>> ascii.write(dat, format='fixed_width_two_line')
Col1 Col2 Col3 Col4
---- --------- ---- ----
1.2 "hello" 1 a
2.4 's worlds 2 2
Write a table as a fixed width table with space padding and '=' position_char: ::
>>> ascii.write(dat, format='fixed_width_two_line',
... delimiter_pad=' ', position_char='=')
Col1 Col2 Col3 Col4
==== ========= ==== ====
1.2 "hello" 1 a
2.4 's worlds 2 2
Write a table as a fixed-width table with no bookend: ::
>>> ascii.write(dat, format='fixed_width_two_line', bookend=True, delimiter='|')
|Col1| Col2|Col3|Col4|
|----|---------|----|----|
| 1.2| "hello"| 1| a|
| 2.4|'s worlds| 2| 2|
自定义标题行#
这个 fixed_width
, fixed_width_two_line
,以及 rst
格式通常包括标题中包含列名的单行。但是,对于这些格式,您可以自定义显示为标题行的列属性。可用的列属性包括 name
, dtype
, format
, description
和 unit
。属性列出所需的标题行来完成此操作。 header_rows
关键字参数。
- ::
>>> from astropy.table.table_helpers import simple_table >>> dat = simple_table(size=3, cols=4) >>> dat["a"].info.unit = "m" >>> dat["d"].info.unit = "m/s" >>> dat["b"].info.format = ".2f" >>> dat["c"].info.description = "C column" >>> ascii.write( ... dat, ... format="fixed_width", ... header_rows=["name", "unit", "format", "description"], ... ) | a | b | c | d | | m | | | m / s | | | .2f | | | | | | C column | | | 1 | 1.00 | c | 4 | | 2 | 2.00 | d | 5 | | 3 | 3.00 | e | 6 |
在本例中,第1行是 name
,第二排是 unit
以此类推。您必须提供 name
中的值 header_rows
列表,以获得包含列名的输出。
具有非标准标题行的表可以使用相同的列表以相同的方式回读 header_rows
**
>>> txt = """\
... | int32 | float32 | <U4 | uint8 |
... | a | b | c | d |
... | m | | | m / s |
... | | .2f | | |
... | | | C column | |
... | 1 | 1.00 | c | 4 |
... | 2 | 2.00 | d | 5 |
... | 3 | 3.00 | e | 6 |
... """
>>> dat = ascii.read(
... txt,
... format="fixed_width",
... header_rows=["dtype", "name", "unit", "format", "description"],
... )
>>> dat.info
<Table length=3>
name dtype unit format description
---- ------- ----- ------ -----------
a int32 m
b float32 .2f
c str4 C column
d uint8 m / s
同样的想法也可以用于 fixed_width_two_line
格式::
>>> txt = """\
... a b c d
... int64 float64 <U1 int64
... m m / s
... ----- ------- -------- -----
... 1 1.00 c 4
... 2 2.00 d 5
... 3 3.00 e 6
... """
>>> dat = ascii.read(
... txt,
... format="fixed_width_two_line",
... header_rows=["name", "dtype", "unit"],
... )
>>> dat
<Table length=3>
a b c d
m m / s
int64 float64 str1 int64
----- ------- ---- -----
1 1.0 c 4
2 2.0 d 5
3 3.0 e 6
请注意, two_line
在 fixed_width_two_line
格式名称是指表头由两行组成的默认情况,即一行列名和一行分隔线。这是一个有点用词不当的用法 header_rows
。