I am playing around with Tables object from astropy.table module.
The piece of code below shows the type of data I am dealing with:
In [44]: table
Out[44]:
<Table length=9>
defocus source Chi2 xcentroid ycentroid FWHMx FWHMy Peak
float32 float32 float32 float32 float32 float32 float32 float32
------- ------- ------- --------- --------- ------- ------- -------
-0.3 0.0 346.648 2056.5 55.82 11.8635 11.8635 182.277
-0.3 4.0 148.302 2056.49 1911.02 6.66554 6.66554 299.074
-0.3 8.0 347.208 2056.51 3922.99 6.83129 6.83129 326.476
-0.26 0.0 318.489 2056.5 55.8803 10.206 10.206 195.055
-0.26 4.0 152.501 2056.51 1911.02 6.9012 6.9012 244.817
-0.26 8.0 285.845 2056.49 3922.99 7.7939 7.7939 236.194
-0.22 0.0 264.113 2056.5 55.9053 8.79704 8.79704 187.376
-0.22 4.0 163.228 2056.5 1911.02 2.43716 2.43716 402.182
-0.22 8.0 230.017 2056.5 3922.99 6.70312 6.70312 235.376
In [45]: type(table)
Out[45]: astropy.table.table.Table
In [46]: cols=table.columns
In [47]: type(cols)
Out[47]: astropy.table.table.TableColumns
In [48]: type(cols[0])
Out[48]: astropy.table.column.Column
In [50]: mylist_1 = [x for x in cols]
In [51]: mylist_2 = [cols[k] for k in range(len(cols))]
In [52]: type(mylist_1[0])
Out[52]: str
In [53]: type(mylist_2[0])
Out[53]: astropy.table.column.Column
In [54]: mylist_1[0]
Out[54]: 'defocus'
In [55]: mylist_2[0]
Out[55]:
<Column name='defocus' dtype='float32' length=9>
-0.3
-0.3
-0.3
-0.26
-0.26
-0.26
-0.22
-0.22
-0.22
I was expecting that the two lines:
mylist_1 = [x for x in cols]
and
mylist_2 = [cols[k] for k in range(len(cols))]
would de exactly the same thing (the second one being less elegant), but it doesn't, as you can see in the outputs above (mylist_1 contains only the columns names, and not the columns themselves). Why is that so? Is there something I don't really understand about my "cols" object?
Thanks for your insights.
(I ran into this while trying to write my table to a fits file - using astropy.io.fits - which requires building an appropriate columns list, which isn't as obvious as one would expect...)
Your loops iterate slightly different (but equivalent) over the columns. But you append different things in the list comprehension. The columns are dict
-like so they have an index and an associated element:
Consider a table like this:
from astropy.table import Table
data_rows = [(1, 2.0, 'x'),
(4, 5.0, 'y'),
(5, 8.2, 'z')]
t = Table(rows=data_rows, names=('a', 'b', 'c'), meta={'name': 'first table'},
dtype=('i4', 'f8', 'S1'))
cols=t.columns
You iterate over the column indices by using:
[x for x in cols]
# ['a', 'b', 'c']
or
[k for k in range(len(cols))]
# [0, 1, 2]
These seem different but cols[0] == cols['a']
so these are just two different ways to index your columns.
But if you want to iterate over the actual columns not their indices you could do:
[cols[x] for x in cols]
# [<Column name='a' dtype='int32' length=3>1 4 5,
# <Column name='b' dtype='float64' length=3>2.0 5.0 8.2,
# <Column name='c' dtype='bytes1' length=3> x y z]
or:
[cols[k] for k in range(len(cols))]
# [<Column name='a' dtype='int32' length=3>1 4 5,
# <Column name='b' dtype='float64' length=3>2.0 5.0 8.2,
# <Column name='c' dtype='bytes1' length=3> x y z]
This time we actually insert the indexed column instead of inserting the index.
This is however no means to your end with the conversion to FITS but you can always save your Table directly into any of their formats see their supported formats.
For example writing to a fits is as simple as using:
t.write('new_table.fits')
or
t.write('new_table.fits', format='fits')