【问题标题】:Use ascii.write() with different column lengths使用具有不同列长度的 ascii.write()
【发布时间】:2017-10-24 16:27:33
【问题描述】:

我想将几个值(浮点数和整数)和数组保存到一个文本文件中。我尝试使用 astropy 表和ascii.write(),但出现值错误。

ValueError: 列表初始化中的元素必须是 Column 或类似列表的

代码:

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

table = Table([x, y, propNum, inc], names=('x', 'y', 'propNum', 'inc'))

ascii.write(table, 'test4.dat')

输入:

x = [6512905, 6291646, 3667192, -358003, -4246455, -6512905, -6291646,  -3667192, 358003, 4246455]
y = [-1739743, 2420707, 5656530, 6731751, 5235671, 1739743, -2420707, -5656530, -6731751, -5235671]
propNum = 100
inc = 51.762

期望的输出:

6512905, -1739743, 100, 51.762
6291646, 2420707
3667192, 5656530
...      ...

【问题讨论】:

  • 你不能把propNuminc的值重复N次吗?

标签: python python-2.7 file numpy astropy


【解决方案1】:

我建议明确创建一个屏蔽表,它在较短列的长度和位置方面提供更大的灵活性:

x = [6512905, 6291646, 3667192, -358003, -4246455, -6512905, -6291646,  -3667192, 358003, 4246455]
y = [-1739743, 2420707, 5656530, 6731751, 5235671, 1739743, -2420707, -5656530, -6731751, -5235671]
propNum = np.concatenate([[100], np.zeros(len(x)-1, dtype='i')])
inc = np.concatenate([[51.762], np.zeros(len(x)-1)])

mtab = Table([x, y, propNum, inc], names=('x', 'y', 'propNum', 'inc'), masked=True)
mtab['propNum'][1:].mask = True
mtab['inc'][1:].mask = True
mtab.write('/dev/stdout', format='ascii', overwrite=True)

x y propNum inc
6512905 -1739743 100 51.762
6291646 2420707 "" ""
3667192 5656530 "" ""
-358003 6731751 "" ""
-4246455 5235671 "" ""
-6512905 1739743 "" ""
-6291646 -2420707 "" ""
-3667192 -5656530 "" ""
358003 -6731751 "" ""
4246455 -5235671 "" ""

我认为可能还有一些选项可以自定义屏蔽值的输出,但我现在无法在文档中挖掘它。

【讨论】:

  • 当简单的列表就足够了,为什么还要使用numpy 数组来表示propNuminc
  • 一般来说,对于科学代码,最好使用 Numpy 数组,尤其是当它们将被用作掩码时(事实上,如果它们还没有,Table 无论如何都会将它们转换为数组) .
  • 而且我认为np.zerosnp.ones 提供了比列表倍数更简洁的界面——除了对于任何显着长度的数据集来说都快得多。虽然在这种情况下,削减np.concatenate 的效率会更高:%timeit inc = [51.762] + 99999999*[0] 1.17 s ± 41 ms per loop (mean ± std. dev. of 7 runs, 1 loop each) %timeit inc = np.concatenate([[51.762], np.zeros(99999999)]) 816 ms ± 4.65 ms per loop (mean ± std. dev. of 7 runs, 1 loop each) %timeit inc = np.zeros(10**9); inc[0] = 51.762 41.1 µs ± 592 ns per loop (mean ± std. dev. of 7 runs, 10000 loop
  • 好点——最好(在这种情况下无论如何)只初始化一个零数组,然后填写几个非零条目。
  • 有没有办法在掩码表中对齐列?
【解决方案2】:

我不确定astropy.table 包是否支持生成具有不同长度列的表。

解决此问题的一种简单方法是重复只有一个元素的列中的值。

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


x = [6512905, 6291646, 3667192, -358003, -4246455, -6512905, -6291646,  -3667192, 358003, 4246455]
y = [-1739743, 2420707, 5656530, 6731751, 5235671, 1739743, -2420707, -5656530, -6731751, -5235671]
propNum = 100
inc = 51.762

table = Table([x, y, [propNum] * len(x), [inc] * len(x)], names=('x', 'y', 'propNum', 'inc'))

ascii.write(table, 'test4.dat')

导致:

x y propNum inc
6512905 -1739743 100 51.762
6291646 2420707 100 51.762
3667192 5656530 100 51.762
-358003 6731751 100 51.762
-4246455 5235671 100 51.762
-6512905 1739743 100 51.762
-6291646 -2420707 100 51.762
-3667192 -5656530 100 51.762
358003 -6731751 100 51.762
4246455 -5235671 100 51.762

同样,您可以扩展最后两列以包含您想要表示空行的任何字符串:

fillVal = 'NA'
propNum = [100] + [fillVal] * (len(x) - 1)
inc = [51.762] + [fillVal] * (len(x) - 1)

table = Table([x, y, propNum, inc], names=('x', 'y', 'propNum', 'inc'))
ascii.write(table, 'test4.dat')

给出:

x y propNum inc
6512905 -1739743 100 51.762
6291646 2420707 NA NA
3667192 5656530 NA NA
-358003 6731751 NA NA
-4246455 5235671 NA NA
-6512905 1739743 NA NA
-6291646 -2420707 NA NA
-3667192 -5656530 NA NA
358003 -6731751 NA NA
4246455 -5235671 NA NA

请注意,这仅在第一行中的缺失值时才有效。如果是,您仍然可以使用这种方法进行一些修改-

【讨论】:

  • 我尝试了 'NA' 解决方案并收到错误消息TypeError: ufunc 'add' did not contain a loop with signature matching types dtype('S32') dtype('S32') dtype('S32')
  • 我尝试了其他解决方案并得到了ValueError: masked should be one of True, False, None
  • 尝试从答案中复制代码并运行该代码。我怀疑您以某种方式修改了原始代码。
  • 最好使用掩码和显式填充值:docs.astropy.org/en/stable/table/masking.html
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-06-27
  • 1970-01-01
  • 2015-05-07
  • 2019-10-17
  • 1970-01-01
  • 2014-07-04
  • 2021-12-07
相关资源
最近更新 更多