如何用pyfits合并两个table?

How to merge two table with pyfits?

我正在使用 Python 2.7.10 和 pyfits 3.3。早些时候,我使用了以下代码来合并两个表。但是,现在我遇到了一些错误

t1 = pyfits.open(table1)[1].columns
t2 = pyfits.open(table2)[1].columns
new_columns = t1 + t2
hdu = pyfits.BinTableHDU.from_columns(new_columns)
hdu.writeto(outtable)

错误是:

Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
 File "/home/vvikraman/anaconda2/lib/python2.7/site-packages/pyfits/hdu/table.py", line 116, in from_columns
    data = FITS_rec.from_columns(coldefs, nrows=nrows, fill=fill)
 File "/home/vvikraman/anaconda2/lib/python2.7/site-packages/pyfits/fitsrec.py", line 315, in from_columns
    if arr.hdu.data is None:
ReferenceError: weakly-referenced object no longer exists

这有点令人困惑,我不是 100% 确定原因,但这是我的猜测:

打开文件本身的结果 pyfits.open(...) 未分配给任何内容,因为您立即访问了第二个 HDU 的列。这给你一个弱参考:基本上,实际数据不再可用,因为该文件在某种意义上(可能是真实的,我没有检查过)已关闭。
Pyfits 这样做是为了节省内存。

令人困惑的部分是,在您分配 t1t2 之后,您仍然可以打印它们的定义,所以看起来实际的列就在附近。事实上,仍然存在的是列定义:无法检索实际数据。因此,当您尝试从 t1t2 的组合创建一个新的二进制 HDU 时,您需要实际数据,但事情会失败。

解决方案是确保您正确引用数据。可能有多种方法可以做到这一点;这似乎对我有用:

hdulist1 = pyfits.open(table1)
hdulist2 = pyfits.open(table2)
t1 = hdulist1[1].columns
t2 = hdulist2[1].columns
new_columns = t1 + t2
hdu = pyfits.BinTableHDU.from_columns(new_columns)
hdu.writeto(outtable)
# explicitly close the HDUs; might free up memory
hdulist1.close()
hdulist2.close()

您有什么理由不能使用 astropy(即 astropy.io.fits)?

在那种情况下,成语将是:

from astropy.table import Table, hstack
t1 = Table.read(table1)
t2 = Table.read(table2)
new = hstack([t1, t2])
new.write(outtable)

readwrite 调用中,如果 table 扩展名不暗示它是 FITS,则您需要提供 format='fits'