lunes, 3 de noviembre de 2025

Tutorial de Pint

 

Tutorial 

Sigue los pasos a continuación y aprende cómo usar Pint para realizar un seguimiento de cantidades físicas y conversiones de unidades en Python.

Inicializando un registro 

Antes de usar Pint, inicialice un UnitRegistry() objeto. Este UnitRegistryalmacena las definiciones de unidades, sus relaciones y gestiona las conversiones entre unidades.

from pint import UnitRegistry
ureg = UnitRegistry()

Si no se proporcionan parámetros al constructor, UnitRegistryse completa con la lista predeterminada de unidades y prefijos.

Definición de una cantidad 

Una vez que hayas inicializado tu sistema UnitRegistry, podrás definir cantidades fácilmente:

distance = 24.0 * ureg.meter
distance
<Quantity(24.0, 'meter')>
print(distance)
24.0 meter

Como puede verse, distanceaquí tenemos un Quantity() objeto que representa una magnitud física. Se puede consultar la magnitud, las unidades y la dimensionalidad de las magnitudes:

distance.magnitude
24.0
distance.units
<Unit('meter')>
print(distance.dimensionality)
[length]

y puede realizar correctamente muchas operaciones matemáticas, incluso con otros Quantity()objetos:

time = 8.0 * ureg.second
print(time)
8.0 second
speed = distance / time
speed
<Quantity(3.0, 'meter / second')>
print(speed)
3.0 meter / second
print(speed.dimensionality)
[length] / [time]

Observe que el analizador integrado reconoce unidades con prefijos y plurales aunque no estén en la lista de definiciones:

distance = 42 * ureg.kilometers
print(distance)
42 kilometer
print(distance.to(ureg.meter))
42000.0 meter

Pint mostrará un error si intentas usar una unidad que no esté en el registro:

speed = 23 * ureg.snail_speed
Traceback (most recent call last):
...
UndefinedUnitError: 'snail_speed' is not defined in the unit registry

Puedes añadir tus propias unidades al registro existente o crear tu propia lista. Consulta la página sobre Definición de unidades para obtener más información.

Consulte Análisis de cadenas y Definición de cantidades para obtener más información sobre cómo definir un Quantity()objeto.

Quantity()Los objetos también funcionan bien con las matrices NumPy, sobre lo cual puedes leer en la sección sobre compatibilidad con NumPy .

Conversión a diferentes unidades 

Como el sistema subyacente UnitRegistryconoce las relaciones entre las diferentes unidades, puede convertir una unidad Quantitya las unidades que desee utilizando el to()método, que acepta una cadena o un Unit()objeto:

speed.to('inch/minute')
<Quantity(7086.61417, 'inch / minute')>
ureg.inch / ureg.minute
<Unit('inch / minute')>
speed.to(ureg.inch / ureg.minute)
<Quantity(7086.61417, 'inch / minute')>

Este método devuelve un nuevo objeto dejando el original intacto, como puede comprobarse a continuación:

print(speed)
3.0 meter / second

Si desea realizar la conversión in situ (es decir, sin crear otro objeto), puede utilizar el ito()método:

speed.ito(ureg.inch / ureg.minute)
speed
<Quantity(7086.61417, 'inch / minute')>
print(speed)
7086.6141... inch / minute

Pint mostrará un error si le pides que realice una conversión que no sabe cómo hacer:

speed.to(ureg.joule)
Traceback (most recent call last):
...
DimensionalityError: Cannot convert from 'inch / minute' ([length] / [time]) to 'joule' ([length] ** 2 * [mass] / [time] ** 2)

Consulte la sección sobre contextos para obtener información sobre cómo ampliar las capacidades de conversión automática de Pint para su aplicación.

Unidades simplificadas 

A veces, la magnitud de la cantidad será muy grande o muy pequeña. El método to_compact()permite ajustar las unidades para que la cantidad sea más fácil de leer:

wavelength = 1550 * ureg.nm
frequency = (ureg.speed_of_light / wavelength).to('Hz')
print(frequency)
193414489032258.03 hertz
print(frequency.to_compact())
193.414489032... terahertz

También existen métodos to_base_units()que ito_base_units()convierten automáticamente a las unidades de referencia con la dimensionalidad correcta:

height = 5.0 * ureg.foot + 9.0 * ureg.inch
print(height)
5.75 foot
print(height.to_base_units())
1.752... meter
print(height)
5.75 foot
height.ito_base_units()
print(height)
1.752... meter

También existen métodos to_reduced_units()que ito_reduced_units()realizan una reducción dimensional simplificada, combinando unidades con la misma dimensionalidad pero manteniendo intactas las definiciones de las unidades.

density = 1.4 * ureg.gram / ureg.cm**3
volume = 10*ureg.cc
mass = density*volume
print(mass)
14.0 cubic_centimeter * gram / centimeter ** 3
print(mass.to_reduced_units())
14.0 gram
print(mass)
14.0 cubic_centimeter * gram / centimeter ** 3
mass.ito_reduced_units()
print(mass)
14.0 gram

Si desea que pint realice automáticamente la reducción dimensional al producir nuevas cantidades, la UnitRegistryclase acepta un parámetro auto_reduce_dimensions. La reducción dimensional puede ser lenta, por lo que la reducción automática está desactivada de forma predeterminada.

Los métodos to_preferred()proporcionan ito_preferred()un mayor control sobre la reducción dimensional al especificar una lista de unidades para combinar y obtener la dimensionalidad requerida.

preferred_units = [
   ureg.ft,  # distance      L
   ureg.slug,  # mass          M
   ureg.s,  # duration      T
   ureg.rankine,  # temperature   Θ
   ureg.lbf,  # force         L M T^-2
   ureg.W,  # power         L^2 M T^-3
]
power = ((1 * ureg.lbf) * (1 * ureg.m / ureg.s)).to_preferred(preferred_units)
print(power)
4.4482216152605005 watt

La lista de unidades preferidas también se puede especificar en el registro de unidades para evitar tener que pasarla en cada llamada a to_preferred().

ureg.default_preferred_units = preferred_units
power = ((1 * ureg.lbf) * (1 * ureg.m / ureg.s)).to_preferred()
print(power)
4.4482216152605005 watt

La UnitRegistryclase acepta un parámetro autoconvert_to_preferred. Si se establece en `true` True, `pint` convertirá automáticamente las unidades a las preferidas al generar nuevas cantidades. Esta opción está desactivada por defecto.

Tenga en cuenta que cuando existen varias combinaciones válidas de unidades para reducir, no se garantiza que `to_preferred` sea repetible. Por ejemplo, puede devolver ` o` o `.(1 * ureg.lbf * ureg.m).to_preferred(preferred_units)W sft lbf

Análisis de cadenas 

Pint incluye un potente análisis de cadenas para identificar magnitudes y unidades. En muchos casos, las unidades pueden definirse como cadenas de texto:

2.54 * ureg('centimeter')
<Quantity(2.54, 'centimeter')>

o utilizando el Quantityconstructor:

Q_ = ureg.Quantity
Q_(2.54, 'centimeter')
<Quantity(2.54, 'centimeter')>

Los números también se analizan, por lo que puede usar una expresión:

ureg('2.54 * centimeter')
<Quantity(2.54, 'centimeter')>
Q_('2.54 * centimeter')
<Quantity(2.54, 'centimeter')>

o bien omitir el * por completo:

Q_('2.54cm')
<Quantity(2.54, 'centimeter')>

Esto te permite crear un sencillo convertidor de unidades en 3 líneas:

user_input = '2.54 * centimeter to inch'
src, dst = user_input.split(' to ')
Q_(src).to(dst)
<Quantity(1.0, 'inch')>

Las cadenas que contienen valores se pueden analizar mediante la ureg.parse_pattern()función. formatSe utiliza como patrón una cadena similar a una cadena con las unidades definidas en ella:

input_string = '10 feet 10 inches'
pattern = '{feet} feet {inch} inches'
ureg.parse_pattern(input_string, pattern)
[<Quantity(10.0, 'foot')>, <Quantity(10.0, 'inch')>]

Para buscar varias coincidencias, configure el manyparámetro en True. El siguiente ejemplo también muestra cómo el analizador puede encontrar coincidencias entre caracteres de relleno:

input_string = '10 feet - 20 feet ! 30 feet.'
pattern = '{feet} feet'
ureg.parse_pattern(input_string, pattern, many=True)
[[<Quantity(10.0, 'foot')>], [<Quantity(20.0, 'foot')>], [<Quantity(30.0, 'foot')>]]

También se puede emplear todo el potencial de las expresiones regulares al escribir patrones:

input_string = "10` - 20 feet ! 30 ft."
pattern = r"{feet}(`| feet| ft)"
ureg.parse_pattern(input_string, pattern, many=True)
[[<Quantity(10.0, 'foot')>], [<Quantity(20.0, 'foot')>], [<Quantity(30.0, 'foot')>]]

Tenga en cuenta que las llaves (``{}``) son convertidas en un patrón de coincidencia de números de punto flotante por el analizador.

Esta función resulta útil para tareas como la extracción masiva de unidades de miles de cadenas uniformes o incluso de textos muy grandes con unidades dispersas sin un patrón determinado.

Formato de cadena 

Las cantidades físicas de pintas se pueden imprimir fácilmente:

accel = 1.3 * ureg.parse_units('meter/second**2')
# The standard string formatting code
print('The str is {!s}'.format(accel))
The str is 1.3 meter / second ** 2
# The standard representation formatting code
print('The repr is {!r}'.format(accel))
The repr is <Quantity(1.3, 'meter / second ** 2')>
# Accessing useful attributes
print('The magnitude is {0.magnitude} with units {0.units}'.format(accel))
The magnitude is 1.3 with units meter / second ** 2

Pint también admite el formato de números de punto flotante para matrices NumPy:

import numpy as np
accel = np.array([-1.1, 1e-6, 1.2505, 1.3]) * ureg.parse_units('meter/second**2')
# float formatting numpy arrays
print('The array is {:.2f}'.format(accel))
The array is [-1.10 0.00 1.25 1.30] meter / second ** 2
# scientific form formatting with unit pretty printing
print('The array is {:+.2E~P}'.format(accel))
The array is [-1.10E+00 +1.00E-06 +1.25E+00 +1.30E+00] m/s²

Pint también admite cadenas f de Python >= 3.6:

accel = 1.3 * ureg.parse_units('meter/second**2')
print(f'The str is {accel}')
The str is 1.3 meter / second ** 2
print(f'The str is {accel:.3e}')
The str is 1.300e+00 meter / second ** 2
print(f'The str is {accel:~}')
The str is 1.3 m / s ** 2
print(f'The str is {accel:~.3e}')
The str is 1.300e+00 m / s ** 2
print(f'The str is {accel:~H}')      # HTML format (displays well in Jupyter)
The str is 1.3 m/s<sup>2</sup>

Pero Pint también amplía las capacidades de formato estándar para representaciones Unicode, LaTeX y HTML:

accel = 1.3 * ureg['meter/second**2']
# Pretty print
'The pretty representation is {:P}'.format(accel)
'The pretty representation is 1.3 meter/second²'
# LaTeX print
'The LaTeX representation is {:L}'.format(accel)
'The LaTeX representation is 1.3\\ \\frac{\\mathrm{meter}}{\\mathrm{second}^{2}}'
# HTML print - good for Jupyter notebooks
'The HTML representation is {:H}'.format(accel)
'The HTML representation is 1.3 meter/second<sup>2</sup>'

Si desea utilizar nombres de unidades abreviados, anteponga el prefijo ~ a la especificación :

'The str is {:~}'.format(accel)
'The str is 1.3 m / s ** 2'
'The pretty representation is {:~P}'.format(accel)
'The pretty representation is 1.3 m/s²'

Lo mismo ocurre con las especificaciones LaTeX ( L ) y HTML ( H ).

Nota

La unidad abreviada se obtiene del registro de unidades, donde se devuelve el tercer elemento de la cadena de equivalencia (es decir, 1 = 2 = 3 ) cuando se utiliza el prefijo '~'. El primer elemento de la cadena es el nombre canónico de la unidad.

Las especificaciones de formato (es decir, 'L', 'H', 'P') se pueden usar con la sintaxis de formato de cadenas de Python para representaciones personalizadas de números de punto flotante. Por ejemplo, notación científica:

'Scientific notation: {:.3e~L}'.format(accel)
'Scientific notation: 1.300\\times 10^{0}\\ \\frac{\\mathrm{m}}{\\mathrm{s}^{2}}'

Pint también admite el paquete LaTeX siunitx :

accel = 1.3 * ureg.parse_units('meter/second**2')
# siunitx Latex print
print('The siunitx representation is {:Lx}'.format(accel))
The siunitx representation is \SI[]{1.3}{\meter\per\second\squared}
accel = accel.plus_minus(0.2)
print('The siunitx representation is {:Lx}'.format(accel))
The siunitx representation is \SI{1.30 +- 0.20}{\meter\per\second\squared}

Además, puede especificar un formato predeterminado:

accel = 1.3 * ureg.parse_units('meter/second**2')
'The acceleration is {}'.format(accel)
'The acceleration is 1.3 meter / second ** 2'
ureg.formatter.default_format = 'P'
'The acceleration is {}'.format(accel)
'The acceleration is 1.3 meter/second²'

Localización 

Si tienes instalado Babel , puedes traducir los nombres de las unidades a cualquier idioma.

ureg.formatter.format_quantity(accel, locale='fr_FR')
'1,3 mètres par seconde²'

También puede especificar la configuración regional del formato en el nivel del registro, ya sea al crear el registro:

ureg = UnitRegistry(fmt_locale='fr_FR')

o más tarde:

ureg.formatter.set_locale('fr_FR')

y, al hacerlo, el formato de cadenas ahora está localizado:

ureg.formatter.default_format = 'P'
accel = 1.3 * ureg.parse_units('meter/second**2')
str(accel)
'1,3 mètres par seconde²'
"%s" % accel
'1,3 mètres par seconde²'
"{}".format(accel)
'1,3 mètres par seconde²'

Si desea personalizar el formato de las cadenas, consulte la sección de formato .

No hay comentarios.:

Publicar un comentario

Entradas recientes

Lifelines o líneas de vidas en Python

  Inicio rápido ¶ Instalación ¶ Instalar mediante  pip : pip install lifelines O Instalar mediante  conda  : conda install -c conda-forge l...

Entradas Populares