What’s New in Astropy 8.1?#

Overview#

Astropy 8.1 is a release that adds significant new functionality since the 8.0 release.

In particular, this release includes:

In addition to these major changes, Astropy v8.1 includes a large number of smaller improvements and bug fixes, which are described in the Full Changelog. By the numbers:

  • X issues have been closed since v8.0

  • X pull requests have been merged since v8.0

  • X distinct people have contributed code

Full change log#

To see a detailed list of all changes in version v8.1, including changes in API, please see the Full Changelog.

Faster Time string formats#

Converting a Time to one of the string-based formats (iso, isot, yday, fits or datetime64) is now done with array operations instead of a Python loop over the individual times. For large arrays this is more than ten times faster, which speeds up printing a Time and writing tables that contain a time column.

Faster Table joins#

The astropy.table.join() function now has the ability to use pandas.merge as the internal engine for join operations. This can speed up the join by up to ~10x for large tables relative to astropy 8.0. This is supported with a new engine option that can have the values "astropy", "pandas", and "auto". The "auto" mode uses pandas if it is available and otherwise falls back to the built-in astropy join implementation.

In addition, the built-in astropy join was sped up by a factor of ~2x for the common case of a single join column.

Controlling the conversion of integers by Quantity#

Creating a Quantity from integer input without giving a dtype upcasts the values to float. That is often what you want since most physical quantities are continuous, but sometimes this is not desired and in the worst case it silently loses precision for large values that float64 cannot represent exactly.

This is now controlled by a new configuration item, astropy.units.quantity.conf.quantity_convert_int_to_float, which takes one of three values: default, always, or never. An explicit dtype argument is always honored regardless of the configuration.

For example:

>>> import astropy.units as u
>>> from astropy.units.quantity import conf
>>> with conf.set_temp("quantity_convert_int_to_float", "never"):
...     q = [1, 2] * u.ct
>>> q.dtype
dtype('int64')

There is also a preserve_dtype_by_default() context manager to preserve the input dtype unless the quantity_convert_int_to_float configuration is set to always.

See Controlling the Conversion of Integers for details.

Integer columns with a unit keep their dtype in a QTable#

An integer Column with a unit added to a QTable is converted to a Quantity, and that conversion used to cast the values to float. It now keeps the integer dtype:

>>> from astropy.table import QTable, Column
>>> t = QTable({"source_id": Column([2741100559643251862], unit="")})
>>> t["source_id"].dtype
dtype('int64')
>>> t["source_id"][0]
<Quantity 2741100559643251862>

Previously the identifier above came back as <Quantity 2.74110056e+18>, a different number from the one that went in. This is an API change: code that relied on such a column being float may need updating, and integer division or overflow behavior now applies where floating point behavior did before.

To restore the previous behavior, set the astropy.units.quantity.conf.quantity_convert_int_to_float configuration value to always, either in your configuration file or for a block of code with set_temp().

Reading files with integer columns that have units#

Reading a file into a QTable goes through the same conversion, so an integer column with a unit read from VOTable, FITS, ECSV, HDF5 or parquet now keeps its dtype rather than being cast to float.

This is strictly speaking an API change, but it is really a bug fix: the previous behavior corrupted values that the file itself stored exactly, with nothing to indicate that anything had been lost. Setting astropy.units.quantity.conf.quantity_convert_int_to_float to always restores the previous behavior if needed.

Contributors to the 8.1 release#