首页 > 解决方案 > 使用 astropy 在 FITS 表中添加一行

问题描述

我有一个应该是微不足道的问题,但似乎由于 FITS BinTableHDU 的基于列的性质而变得过于复杂。

我正在编写的脚本应该很简单:遍历 FITS 文件并将行的子集写入格式相同的 FITS 文件,从而将行数从 c700k/3.6GB 减少到大约 350 行。我已经处理了输入文件并将每一行我想保存在一个 FITS 记录的 python 数组中:

    outarray = []

    self.indata=Table.read(self.infile, hdu=1)
    
    for r in self._indata:

        RecPassesFilter = FilterProc(r, self)

        #
        # Add to output array only if passes all filters...  
        #   
        if RecPassesFilter:
            outarray.append(r)

现在,我创建了一个具有完全相同列和格式的空 BintableHDU,我想添加过滤后的数据:

[...后面省略了很多代码...}

            mycols =  []
            for inputcol in self._coldefs:
                mycols.append(fits.Column(name=inputcol.name, format=inputcol.format))

           # Next line should produce an empty BinTableHDU in the identical format to the output data

            SaveData = fits.BinTableHDU.from_columns(mycols)

            for s in self._outdata:
                SaveData.data.append(s)

现在,最后一行不仅失败了,而且它的每个变体(SaveData.append() 或 .add_row() 或其他)也因“没有这样的方法”错误而失败。似乎很少有关于如何完成添加记录的琐碎任务的文档。显然我错过了一些东西,但两天后我仍然在画一个空白。

谁能在这里指出我正确的方向?

标签: astropyfits

解决方案


好的,我设法通过一些蛮力和嵌套迭代来解决这个问题,本质上是动态创建列数据数组。它在代码方面并不多,我不在乎它效率低下,因为我不需要经常运行它。这里的示例代码:

            with fits.open(self._infile) as HDUSet:
                tableHDU=HDUSet[1]
                self._coldefs = tableHDU.columns

            
            FITScols =  []
            for inputcol in self._coldefs:
                NewColData = []
                for r in self._outdata:
                    NewColData.append(r[inputcol.name])
                FITScols.append(fits.Column(name=inputcol.name, format=inputcol.format, array=NewColData))

            SaveData = fits.BinTableHDU.from_columns(FITScols)

            SaveData.writeto(fname)

这解决了我对 350 行子集的问题。我还不敢尝试下一个项目所需的 250K 行子集!


推荐阅读