Эффективно экспортировать массив Astropy SkyCoord в массив / DataFrame / файл - PullRequest
1 голос
/ 09 января 2020

Координаты Astropy оказались очень быстрым способом преобразования между ICRS и кадрами Galacti c. Мой вопрос касается записи массива SkyCoord в текстовый файл, возможно, с использованием массива Numpy или Pandas DataFrame в качестве посредника. Мои массивы довольно большие (~ 100K координат), поэтому эффективность желательна.

Кажется, что в классе SkyCoord нет методов для экспорта RA / De c как любого Python встроенного в структуре данных. Один из возможных маршрутов, которые я исследовал, - это создание Astropy QTable для координат (который добавляет их в виде строк), но это медленный процесс, требующий дополнительной обработки для разделения и очистки строк координат.

Например

import numpy as np
import pandas as pd
from astropy import units as u
from astropy.coordinates import SkyCoord
from astropy.io import ascii
from astropy.table import QTable

if __name__ == "__main__":
    RA = np.array([0.819853, 0.0920091, 1.04977])
    DEC = np.array([-30.8484, -30.671, -31.0921])

    c = SkyCoord(ra=RA * u.degree, dec=DEC * u.degree, frame="icrs")
    c_galactic = c.galactic

    table = QTable([c_galactic], names=["skycoord"])
    ascii.write(
        table, "gal_coords.csv", format="csv", fast_writer=False, overwrite=True
    )

Любые предложения о наилучшем способе достижения этой цели будут приветствоваться. Если решение универсально для преобразования массивов SkyCoord в другие структуры данных, я надеюсь, что это будет полезно для более широкого сообщества.

Ответы [ 3 ]

3 голосов
/ 09 января 2020

Astropy имеет встроенную функциональность для обработки экспорта столбца координат в таблице в CSV с использованием формата ECSV , см. Пример ниже. При этом автоматически генерируются имена столбцов, соответствующие исходному столбцу с соответствующими атрибутами координат, в этом случае l и b для Galacti c.

ECSV является расширением CSV, которое включает метаданные в закомментированный текст в начале файла, чтобы полностью указать данные столбца и разрешить передачу данных без потерь. Важно отметить, что вы можете прочитать это с любым читателем CSV (не только астропией), указав, что # является комментарием (например, pandas.read_csv(..., comment='#').

>>> RA = np.array([0.819853, 0.0920091, 1.04977])
... DEC = np.array([-30.8484, -30.671, -31.0921])
... 
... c = SkyCoord(ra=RA * u.degree, dec=DEC * u.degree, frame="icrs")
... c_galactic = c.transform_to("galactic")
...
>>> t = QTable([c_galactic], names=["skycoord"])
>>> t.write('skycoord.ecsv')
>>> cat skycoord.ecsv
# %ECSV 0.9
# ---
# datatype:
# - {name: skycoord.l, unit: deg, datatype: float64}
# - {name: skycoord.b, unit: deg, datatype: float64}
# meta: !!omap
# - __serialized_columns__:
#     skycoord:
#       __class__: astropy.coordinates.sky_coordinate.SkyCoord
# ...
# schema: astropy-2.0
skycoord.l skycoord.b
10.618564158206215 -78.83862258651922
12.320325970465513 -78.28290679292496
9.106328561289311 -78.95458548581124

>>> pd.read_csv('skycoord.ecsv', comment='#')
                   skycoord.l skycoord.b
0  10.618564158206215 -78.83862258651922
1  12.320325970465513 -78.28290679292496
2   9.106328561289311 -78.95458548581124
0 голосов
/ 09 января 2020

Еще один способ подойти к этому без использования ECSV будет просто:

>>> RA = np.array([0.819853, 0.0920091, 1.04977])
... DEC = np.array([-30.8484, -30.671, -31.0921])
... 
... c = SkyCoord(ra=RA * u.degree, dec=DEC * u.degree, frame="icrs")
... c_galactic = c.transform_to("galactic")
...
>>> t = QTable([c_galactic], names=["skycoord"])
>>> t.to_pandas().to_csv('skycoord.csv', index=False)
>>> cat skycoord.csv
skycoord.l,skycoord.b
10.618564158206215,-78.83862258651922
12.320325970465513,-78.28290679292496
9.106328561289311,-78.95458548581124

Этот подход отбрасывает любые метаданные, но работает легко.

0 голосов
/ 09 января 2020

Я, возможно, был немного доволен этим вопросом SO; немного больше копая, я нашел то, что я был после. Надеюсь, что решение полезно для других:

import numpy as np
import pandas as pd
from astropy import units as u
from astropy.coordinates import SkyCoord

if __name__ == "__main__":
    RA = np.array([0.819853, 0.0920091, 1.04977])
    DEC = np.array([-30.8484, -30.671, -31.0921])

    c = SkyCoord(ra=RA * u.degree, dec=DEC * u.degree, frame="icrs")

    c_galactic = c.transform_to("galactic")

    coord_df = pd.DataFrame({"l": c_galactic.l.degree, "b": c_galactic.b.degree})
    coord_df.to_csv("gal_coords.csv", index=False)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...