Skip to content
Open

Doc qto #2289

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/user/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ examples that describe many common tasks that you can accomplish with pint.
:hidden:

defining-quantities
quantity-to
formatting
nonmult
log_units
Expand Down
329 changes: 329 additions & 0 deletions docs/user/quantity-to.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,329 @@
.. _quantity-to:

Unit Conversion Methods
=======================

Pint quantities provide several methods for converting to different units. This page
covers all ``to_*`` and ``ito_*`` methods available on a :class:`Quantity
<pint.quantity.Quantity>`.

The ``ito_*`` variants perform the conversion **in place** (modifying the quantity),
while the ``to_*`` variants return a **new** quantity and can be chained.

Setup used throughout this page:

.. doctest::

>>> import pint
>>> ureg = pint.UnitRegistry()
>>> Q_ = ureg.Quantity


Summary Table
-------------

.. Generated by:
..
.. import pandas as pd
.. import pint
..
.. ureg = pint.UnitRegistry()
.. Q_ = ureg.Quantity
..
.. quantities = [Q_(5000, "m"), Q_(200e-9, "s"), Q_(1e6, "mW"), Q_(1, "N*m"), Q_(1e-7, "Hz")]
.. inputs = {fmt(q): q for q in quantities}
..
.. conversions = {
.. ".to_base_units()": lambda q: q.to_base_units(),
.. ".to_root_units()": lambda q: q.to_root_units(),
.. ".to_compact()": lambda q: q.to_compact(),
.. ".to_reduced_units()": lambda q: q.to_reduced_units(),
.. ".to_unprefixed()": lambda q: q.to_unprefixed(),
.. ".to_base_units().to_compact()": lambda q: q.to_base_units().to_compact(),
.. ".to_reduced_units().to_compact()": lambda q: q.to_reduced_units().to_compact(),
.. ".to_preferred([ureg.W, ureg.s, ureg.J, ureg.m])": lambda q: q.to_preferred([ureg.W, ureg.s, ureg.J, ureg.m]),
.. }
..
.. def fmt(q):
.. return f"{q.magnitude:.6g} {q.units:~P}"
..
.. rows = {method: {col: fmt(fn(q)) for col, q in inputs.items()} for method, fn in conversions.items()}
.. df = pd.DataFrame(rows).T
.. df.index.name = "Method"
.. df

.. raw:: html

<table border="1" class="dataframe">
<thead>
<tr style="text-align: right;">
<th></th>
<th>5000 m</th>
<th>2e-07 s</th>
<th>1e+06 mW</th>
<th>1 m·N</th>
<th>1e-07 Hz</th>
</tr>
<tr>
<th>Method</th>
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
<tr>
<th>.to_base_units()</th>
<td>5000 m</td>
<td>2e-07 s</td>
<td>1000 kg·m²/s³</td>
<td>1 kg·m²/s²</td>
<td>1e-07 1/s</td>
</tr>
<tr>
<th>.to_root_units()</th>
<td>5000 m</td>
<td>2e-07 s</td>
<td>1e+06 g·m²/s³</td>
<td>1000 g·m²/s²</td>
<td>1e-07 1/s</td>
</tr>
<tr>
<th>.to_compact()</th>
<td>5 km</td>
<td>200 ns</td>
<td>1 kW</td>
<td>1 m·N</td>
<td>100 nHz</td>
</tr>
<tr>
<th>.to_reduced_units()</th>
<td>5000 m</td>
<td>2e-07 s</td>
<td>1e+06 mW</td>
<td>1 m·N</td>
<td>1e-07 Hz</td>
</tr>
<tr>
<th>.to_unprefixed()</th>
<td>5000 m</td>
<td>2e-07 s</td>
<td>1000 W</td>
<td>1 m·N</td>
<td>1e-07 Hz</td>
</tr>
<tr>
<th>.to_base_units().to_compact()</th>
<td>5 km</td>
<td>200 ns</td>
<td>1 Mg·m²/s³</td>
<td>1 kg·m²/s²</td>
<td>100 1/Gs</td>
</tr>
<tr>
<th>.to_reduced_units().to_compact()</th>
<td>5 km</td>
<td>200 ns</td>
<td>1 kW</td>
<td>1 m·N</td>
<td>100 nHz</td>
</tr>
<tr>
<th>.to_preferred([ureg.W, ureg.s, ureg.J, ureg.m])</th>
<td>5000 m</td>
<td>2e-07 s</td>
<td>1000 W</td>
<td>1 J</td>
<td>1e-07 1/s</td>
</tr>
</tbody>
</table>

.. note::

``.to_compact()`` and ``.to_unprefixed()`` only change the SI prefix and
rescale the magnitude accordingly — the unit type is preserved (e.g. ``mW``
stays as watts, ``km`` stays as metres). In contrast, ``.to_base_units()``,
``.to_root_units()``, ``.to_reduced_units()``, and ``.to_preferred()`` can
change the unit entirely (e.g. ``N·m`` becomes ``J``, ``kg·m²/s²``).

.. note::

``.to_base_units().to_compact()`` on a prefixed unit like ``mW`` expands to
base SI units (``kg·m²/s³``) before rescaling — the result (``Mg·m²/s³``) is
numerically correct but less readable. Use ``.to_reduced_units().to_compact()``
to stay in named units like ``kW``.

.. note::

``.to_preferred()`` requires ``scipy``. See :ref:`to_preferred_section` below.


to / ito
--------

Convert to specific units by passing a unit string, unit object, or another quantity.

.. doctest::

>>> distance = 1000 * ureg.meter
>>> distance.to("km")
<Quantity(1.0, 'kilometer')>
>>> speed = Q_(60, "miles/hour")
>>> speed.to("km/hour")
<Quantity(96.56064, 'kilometer / hour')>

``ito`` modifies in place:

.. doctest::

>>> distance = 1000 * ureg.meter
>>> distance.ito("km")
>>> distance
<Quantity(1.0, 'kilometer')>


to_base_units / ito_base_units
-------------------------------

Convert to base units as defined by the unit registry (SI base units by default).

.. doctest::

>>> Q_(1, "km").to_base_units()
<Quantity(1000.0, 'meter')>
>>> Q_(1, "hour").to_base_units()
<Quantity(3600.0, 'second')>
>>> Q_(1, "newton").to_base_units()
<Quantity(1.0, 'kilogram * meter / second ** 2')>


to_root_units / ito_root_units
-------------------------------

Convert to root units — the primitive units before any system-level
transformations. For most units this matches ``to_base_units``, but differs for
units like ``mW`` where the root unit uses grams rather than kilograms.

.. doctest::

>>> Q_(1, "km").to_root_units()
<Quantity(1000.0, 'meter')>
>>> Q_(1, "newton").to_root_units()
<Quantity(1.0, 'kilogram * meter / second ** 2')>


to_reduced_units / ito_reduced_units
--------------------------------------

Reduce to one unit per dimension, cancelling units where possible. This does not
reduce compound units like ``J/kg`` to ``m²/s²``.

.. doctest::

>>> Q_(1, "m * km").to_reduced_units()
<Quantity(1000.0, 'meter ** 2')>
>>> Q_(1, "m/km").to_reduced_units()
<Quantity(0.001, '')>


to_compact / ito_compact
-------------------------

Rescale to the most human-readable SI-prefixed unit for the magnitude.

.. doctest::

>>> Q_(0.00042, "m").to_compact()
<Quantity(0.42, 'millimeter')>
>>> Q_(12000, "m").to_compact()
<Quantity(12.0, 'kilometer')>
>>> Q_(5e-9, "s").to_compact()
<Quantity(5.0, 'nanosecond')>

Pass a unit to compact within a specific unit family:

.. doctest::

>>> Q_(0.01, "kg * m / s**2").to_compact("N")
<Quantity(10.0, 'millinewton')>


.. _to_preferred_section:

to_preferred / ito_preferred
-----------------------------

Convert to a unit composed of a given list of preferred units. Requires ``scipy``.
If no preferred units are given, the registry's ``default_preferred_units`` are used.

.. doctest::

>>> Q_(1, "acre").to_preferred([ureg.meter])
<Quantity(4046.87261, 'meter ** 2')>
>>> Q_(1, "km/hour").to_preferred([ureg.mile])
<Quantity(0.62137119, 'mile / hour')>
>>> Q_(4.184, "J").to_preferred([ureg.W, ureg.s])
<Quantity(4.184, 'watt * second')>


to_unprefixed / ito_unprefixed
--------------------------------

Remove SI prefixes without converting to base units. Useful when you want the
unprefixed form of a unit while staying in the same unit family.

.. doctest::

>>> Q_(1, "km").to_unprefixed()
<Quantity(1000.0, 'meter')>
>>> Q_(1, "ms").to_unprefixed()
<Quantity(0.001, 'second')>
>>> Q_(1, "MW").to_unprefixed()
<Quantity(1000000.0, 'watt')>


to_tuple
--------

Serialize a quantity to a ``(magnitude, unit_items)`` tuple. Can be reconstructed
with :meth:`Quantity.from_tuple`.

.. doctest::

>>> q = Q_(1.5, "m/s")
>>> tup = q.to_tuple()
>>> tup
(1.5, (('meter', 1), ('second', -1)))
>>> Q_.from_tuple(tup)
<Quantity(1.5, 'meter / second')>


to_timedelta
------------

Convert a time quantity to a :class:`datetime.timedelta` object.

.. doctest::

>>> import datetime
>>> Q_(2.5, "hours").to_timedelta()
datetime.timedelta(seconds=9000)
>>> Q_(500, "ms").to_timedelta()
datetime.timedelta(microseconds=500000)


Chaining Conversions
--------------------

Since ``to_*`` methods return new quantities, they can be chained. The ``ito_*``
variants return ``None`` and cannot be chained.

.. doctest::

>>> Q_(1, "m * km").to_reduced_units().to_compact()
<Quantity(1.0, 'kilometer ** 2')>
>>> Q_(1, "Wh").to_base_units().to_compact()
<Quantity(3.6, 'kilojoule')>
2 changes: 2 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,8 @@ doctest = "sphinx-build -a -j auto -b doctest -d build/doctrees docs build/docte

[tool.pixi.feature.docs.dependencies]
pandoc = "*"
pandas = "*"
tabulate = "*"

[tool.pixi.feature.py311.dependencies]
python = "3.11.*"
Expand Down
Loading