Python 使用具有不同列长度的ascii.write()

Python 使用具有不同列长度的ascii.write(),python,python-2.7,file,numpy,astropy,Python,Python 2.7,File,Numpy,Astropy,我想将几个值(浮点和整数)和数组保存到一个文本文件中。我尝试使用astropy表和ascii.write(),但得到一个值错误 ValueError:列表初始化中的元素必须是列或类似列表的元素 代码: 投入: x = [6512905, 6291646, 3667192, -358003, -4246455, -6512905, -6291646, -3667192, 358003, 4246455] y = [-1739743, 2420707, 5656530, 6731751, 5235

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

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

代码:

投入:

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
...      ...

我不确定
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

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

我不确定
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

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

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

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 "" ""

我认为还可以选择自定义屏蔽值的输出,但我现在无法在文档中找到它。

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

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 "" ""


我认为还可以选择定制屏蔽值的输出,但是我现在无法在文档中找到它。

你不能只重复
propNum
inc
值N次吗?你不能只重复
propNum
inc
值N次吗?我尝试了“NA”解决方案,得到了一条错误消息
TypeError:ufunc'add'不包含带签名的循环匹配类型dtype('S32')dtype('S32')dtype('S32')
我尝试了另一种解决方案,得到了
ValueError:masked应该是True、False、None中的一种
尝试从答案中复制代码并运行该代码。我怀疑您以某种方式修改了原始代码。最好使用掩码和显式填充值:我尝试了“NA”解决方案,并收到一条错误消息
TypeError:ufunc'add'不包含具有签名匹配类型dtype('S32')dtype('S32')dtype('S32')的循环
我尝试了另一种解决方案,得到了
ValueError:masked应该是True、False、None中的一种
尝试从答案中复制代码并运行该代码。我怀疑您以某种方式修改了原始代码。最好使用掩码和显式填充值:当简单的列表足够时,为什么要对
propNum
inc
使用
numpy数组?一般来说,对于科学代码,最好使用numpy数组,尤其是当它们将用作掩码时(事实上,如果尚未将它们转换为数组,表将以任何方式将它们转换为数组)。我认为
np.zero
np.one
比列表的倍数更干净,而且对于任何有效长度的数据集都要快得多。虽然在这种情况下,减少
np.concatenate
的效率会更高:
%timeit inc=[51.762]+999999999*[0]1.17 s±41 ms/循环(7次运行的平均值±标准偏差,每个循环1次)%timeit inc=np.串联([[51.762],np.零点(99999999)])816 ms±4.65 ms/循环(7次运行的平均值±标准偏差,每个循环1次)%timeit inc=np.零点(10**9);inc[0]=51.762 41.1µs±592 ns/循环(7次运行的平均值±标准偏差,10000个循环)
好点——更好(在这种情况下)初始化一个零数组,然后填入几个非零条目。有没有办法证明屏蔽表中的列是正确的?当简单的列表足够时,为什么要对
propNum
inc
使用
numpy
数组?一般来说,对于科学代码来说,最好使用numpy数组,尤其是当它们不可用时o可用作掩码(事实上,如果尚未将它们转换为数组,表将以任何方式将它们转换为数组)。我认为
np.zero
np.one
比列表的倍数更干净,而且对于任何有效长度的数据集都要快得多。虽然在这种情况下,减少
np.concatenate
的效率会更高:
%timeit inc=[51.762]+999999999*[0]1.17 s±41 ms/循环(7次运行的平均值±标准偏差,每个循环1次)%timeit inc=np.串联([[51.762],np.零点(99999999)])816 ms±4.65 ms/循环(7次运行的平均值±标准偏差,每个循环1次)%timeit inc=np.零点(10**9);inc[0]=51.762 41.1µs±592 ns/循环(7次运行的平均值±标准偏差,10000个循环)
好点——更好(在这种情况下)初始化一个零数组,然后填充几个非零项。有没有办法在屏蔽表中对齐列?