Astronomy and astrophysics core library providing comprehensive tools for astronomical computations and data handling
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Flexible table data structure with metadata support, advanced I/O capabilities, table operations (join, stack, group), and integration with units and coordinates.
Create and manipulate heterogeneous data tables with column metadata, units, and astronomical data types.
class Table:
"""
Heterogeneous table of data with metadata support.
Parameters:
- data: input data (dict, list, array, etc.)
- masked: whether to use masked arrays
- names: column names
- meta: table metadata dictionary
- copy: whether to copy input data
- rows: input data as rows instead of columns
- copy_indices: whether to copy indices
"""
def __init__(self, data=None, masked=None, names=None, meta=None,
copy=True, rows=None, copy_indices=True, **kwargs): ...
@classmethod
def read(cls, *args, **kwargs):
"""
Read table from file.
Supports formats: ASCII, FITS, VOTable, HDF5, CSV, etc.
Parameters:
- filename: file to read
- format: file format (auto-detected if not specified)
- **kwargs: format-specific options
Returns:
Table: loaded table
"""
def write(self, *args, **kwargs):
"""
Write table to file.
Parameters:
- filename: output filename
- format: output format
- **kwargs: format-specific options
"""
def copy(self, copy_data=True):
"""Create a copy of the table."""
def __getitem__(self, item):
"""Get column(s) or row(s) from table."""
def __setitem__(self, item, value):
"""Set column or row values."""
def __len__(self):
"""Number of rows in table."""
@property
def colnames(self):
"""List of column names."""
@property
def meta(self):
"""Table metadata dictionary."""
def add_column(self, col, index=None, name=None, rename_duplicate=False):
"""Add a column to the table."""
def add_columns(self, cols, indexes=None, names=None, copy=True):
"""Add multiple columns to the table."""
def remove_column(self, name):
"""Remove a column from the table."""
def remove_columns(self, names):
"""Remove multiple columns from the table."""
def rename_column(self, name, new_name):
"""Rename a column."""
def add_row(self, vals=None, mask=None):
"""Add a row to the table."""
def insert_row(self, index, vals=None, mask=None):
"""Insert a row at the specified index."""
def remove_row(self, index):
"""Remove a row from the table."""
def remove_rows(self, row_specifier):
"""Remove multiple rows from the table."""
class QTable(Table):
"""
Table subclass with enhanced Quantity support.
Automatically handles unit conversions and quantity operations.
"""
def __init__(self, *args, **kwargs): ...Individual column management with metadata, units, and data type support.
class Column:
"""
Table column with metadata and unit support.
Parameters:
- data: column data
- name: column name
- unit: physical unit
- description: column description
- meta: column metadata dictionary
- mask: mask for missing values
"""
def __init__(self, data=None, name=None, unit=None, description=None,
meta=None, mask=None, **kwargs): ...
@property
def name(self):
"""Column name."""
@property
def unit(self):
"""Column unit."""
@property
def description(self):
"""Column description."""
@property
def meta(self):
"""Column metadata."""
@property
def dtype(self):
"""Column data type."""
def to(self, unit):
"""Convert column to different unit."""
def copy(self, data=None, copy_data=True):
"""Create a copy of the column."""
class MaskedColumn(Column):
"""Column supporting masked arrays for missing data."""
def __init__(self, *args, **kwargs): ...
@property
def mask(self):
"""Boolean mask for missing values."""
@property
def filled_data(self):
"""Data with masked values filled."""
class Row:
"""
Single row from a table.
Provides dict-like access to column values in a row.
"""
def __init__(self, table, index): ...
def __getitem__(self, item):
"""Get value for column."""
def __setitem__(self, item, value):
"""Set value for column."""
def keys(self):
"""Column names in the row."""
def values(self):
"""Values in the row."""Advanced table operations including joining, stacking, grouping, and sorting.
def join(left, right, keys=None, join_type='inner', uniq_col_name='{col_name}_{table_name}',
table_names=['1', '2'], metadata_conflicts='warn'):
"""
Join two tables on matching column values.
Parameters:
- left, right: tables to join
- keys: column names to join on
- join_type: 'inner', 'outer', 'left', 'right', 'cartesian'
- uniq_col_name: format for non-unique column names
- table_names: names for tables in case of conflicts
- metadata_conflicts: how to handle metadata conflicts
Returns:
Table: joined table
"""
def vstack(tables, join_type='outer', metadata_conflicts='warn'):
"""
Vertically stack tables (concatenate rows).
Parameters:
- tables: list of tables to stack
- join_type: how to handle column differences
- metadata_conflicts: metadata conflict resolution
Returns:
Table: stacked table
"""
def hstack(tables, uniq_col_name='{col_name}_{table_name}', table_names=None):
"""
Horizontally stack tables (concatenate columns).
Parameters:
- tables: list of tables to stack
- uniq_col_name: format for duplicate column names
- table_names: names for identifying tables
Returns:
Table: horizontally stacked table
"""
def dstack(tables):
"""
Stack tables along a new dimension.
Parameters:
- tables: list of tables to stack
Returns:
Table: table with additional dimension
"""
def unique(input_table, keys=None, silent=False):
"""
Find unique rows in table.
Parameters:
- input_table: input table
- keys: columns to consider for uniqueness
- silent: suppress warnings
Returns:
Table: table with unique rows
"""
def setdiff(table1, table2, keys=None):
"""
Set difference between two tables.
Returns:
Table: rows in table1 but not in table2
"""Group tables by column values and perform aggregation operations.
class TableGroups:
"""
Container for grouped table operations.
Created by Table.group_by() method.
"""
def __init__(self, parent_table, indices=None, keys=None): ...
def aggregate(self, func):
"""
Aggregate groups using function.
Parameters:
- func: aggregation function or dict of column -> function
Returns:
Table: aggregated results
"""
@property
def groups(self):
"""List of group tables."""
@property
def keys(self):
"""Group key values."""
def __iter__(self):
"""Iterate over groups."""
def __getitem__(self, item):
"""Get specific group."""
# Table grouping method
def group_by(self, keys):
"""
Group table by column values.
Parameters:
- keys: column name(s) to group by
Returns:
TableGroups: grouped table container
"""
# This method is added to Table class
Table.group_by = group_bySpecial support for astronomical coordinates and sky coordinate columns.
def join_skycoord(distance_threshold=None):
"""
Join tables based on sky coordinate proximity.
Parameters:
- distance_threshold: maximum separation for matches
Returns:
function: join function for coordinate-based matching
"""
# SkyCoord column support in tables
# SkyCoord objects can be stored directly as table columns
from astropy.coordinates import SkyCoord
import astropy.units as u
# Create table with coordinate column
ra = [10.1, 20.2, 30.3] * u.degree
dec = [40.1, 50.2, 60.3] * u.degree
coords = SkyCoord(ra=ra, dec=dec)
table = Table()
table['name'] = ['star1', 'star2', 'star3']
table['coords'] = coords
table['magnitude'] = [12.1, 13.2, 14.3]Comprehensive I/O support for astronomical and scientific data formats.
# Supported formats for Table.read() and Table.write():
# ASCII formats:
# - 'ascii' - basic ASCII
# - 'ascii.fixed_width' - fixed width columns
# - 'ascii.csv' - comma-separated values
# - 'ascii.tab' - tab-separated values
# - 'ascii.latex' - LaTeX table format
# - 'ascii.html' - HTML table format
# - 'ascii.rst' - reStructuredText format
# - 'ascii.daophot' - DAOPHOT format
# - 'ascii.sextractor' - SExtractor catalog format
# - 'ascii.cds' - CDS format
# - 'ascii.mrt' - Machine Readable Table format
# Binary formats:
# - 'fits' - FITS binary tables
# - 'votable' - VOTable format
# - 'hdf5' - HDF5 format
# - 'parquet' - Apache Parquet format
# Registry system for custom formats
from astropy.table import registry
def custom_reader(filename, **kwargs):
"""Custom table reader function."""
# Implementation
pass
def custom_writer(table, filename, **kwargs):
"""Custom table writer function."""
# Implementation
pass
registry.register_reader('custom', Table, custom_reader)
registry.register_writer('custom', Table, custom_writer)Control table display, formatting, and pretty-printing options.
class TableFormatter:
"""Control table display formatting."""
def __init__(self, table): ...
@property
def max_lines(self):
"""Maximum lines to display."""
@property
def max_width(self):
"""Maximum width for display."""
# Table display configuration (accessed via table.pformat(), table.pprint())
def pformat(self, max_lines=None, max_width=None, show_name=True,
show_unit=None, show_dtype=False, align=None):
"""
Format table as string.
Parameters:
- max_lines: maximum lines to show
- max_width: maximum width
- show_name: show column names
- show_unit: show column units
- show_dtype: show column data types
- align: column alignment
Returns:
str: formatted table string
"""
def pprint(self, *args, **kwargs):
"""Pretty-print table to console."""
# Add these methods to Table class
Table.pformat = pformat
Table.pprint = pprintfrom astropy.table import Table, Column
import astropy.units as u
import numpy as np
# Create table from dictionary
data = {
'name': ['Sirius', 'Canopus', 'Rigel'],
'ra': [101.3, 95.5, 78.6] * u.degree,
'dec': [-16.7, -52.7, -8.2] * u.degree,
'magnitude': [1.46, 0.74, 0.13],
'distance': [8.6, 310, 860] * u.lightyear
}
stars = Table(data)
print(stars)
print(f"Number of stars: {len(stars)}")
print(f"Column names: {stars.colnames}")# Create two related tables
catalog1 = Table({
'id': [1, 2, 3],
'name': ['Star A', 'Star B', 'Star C'],
'magnitude': [12.1, 13.2, 14.3]
})
catalog2 = Table({
'id': [1, 2, 4],
'parallax': [0.1, 0.05, 0.02] * u.arcsec,
'proper_motion': [10, 5, 2] * u.mas/u.year
})
# Join tables on 'id' column
combined = join(catalog1, catalog2, keys='id', join_type='inner')
print(combined)
# Stack tables vertically
more_stars = Table({
'id': [5, 6],
'name': ['Star D', 'Star E'],
'magnitude': [15.1, 16.2]
})
all_stars = vstack([catalog1, more_stars])from astropy.table import QTable
# QTable provides better Quantity support
qtable = QTable()
qtable['name'] = ['Vega', 'Altair', 'Deneb']
qtable['flux'] = [1000, 500, 200] * u.Jy
qtable['wavelength'] = [550, 600, 650] * u.nm
# Unit conversions
qtable['flux_cgs'] = qtable['flux'].to(u.erg / u.s / u.cm**2 / u.Hz)
qtable['freq'] = qtable['wavelength'].to(u.Hz, equivalencies=u.spectral())
print(qtable['flux', 'flux_cgs', 'freq'])from astropy.coordinates import SkyCoord
# Table with coordinate columns
coord_table = Table()
coord_table['source'] = ['NGC1234', 'M31', 'M87']
# Add SkyCoord column directly
ra = [123.4, 10.7, 187.7] * u.degree
dec = [56.7, 41.3, 12.4] * u.degree
coord_table['coords'] = SkyCoord(ra=ra, dec=dec)
# Add individual coordinate columns
coord_table['ra'] = coord_table['coords'].ra
coord_table['dec'] = coord_table['coords'].dec
coord_table['l'] = coord_table['coords'].galactic.l
coord_table['b'] = coord_table['coords'].galactic.b
print(coord_table)# Table with multiple observations per object
observations = Table({
'object': ['Star1', 'Star1', 'Star2', 'Star2', 'Star3'],
'filter': ['B', 'V', 'B', 'V', 'B'],
'magnitude': [12.1, 11.8, 13.2, 12.9, 14.1],
'error': [0.1, 0.1, 0.15, 0.12, 0.2]
})
# Group by object
grouped = observations.group_by('object')
# Aggregate - calculate mean magnitude per object
mean_mags = grouped.aggregate(np.mean)
print(mean_mags)
# Custom aggregation
def weighted_mean(group):
weights = 1 / group['error']**2
return np.average(group['magnitude'], weights=weights)
weighted_mags = grouped.aggregate({'magnitude': weighted_mean})# Write table to various formats
stars.write('catalog.fits', format='fits')
stars.write('catalog.csv', format='ascii.csv')
stars.write('catalog.votable', format='votable')
# Read tables
fits_table = Table.read('catalog.fits')
csv_table = Table.read('catalog.csv', format='ascii.csv')
# Format-specific options
stars.write('formatted.txt', format='ascii.fixed_width',
delimiter=' ', bookend=False)
# Read with custom options
custom_table = Table.read('data.txt', format='ascii',
names=['col1', 'col2', 'col3'],
data_start=3)# Control display options
stars.pprint(max_lines=10, max_width=80, show_unit=True)
# Custom formatting for specific columns
stars['ra'].format = '%.3f'
stars['dec'].format = '%.3f'
stars['magnitude'].format = '%.2f'
# Export formatted table
formatted_output = stars.pformat(show_name=True, show_unit=True, align=['<', '>', '^'])
print(formatted_output)