如何测试 Pint 中的单位等效性?例如,
nM
相当于 nmol/L
,L
相当于 dm^3
,但根据 Pint,它们并不相等。我不需要兼容性,Pint 通过 is_compatible_with
方法提供了兼容性。例如,s
与 ms
兼容,但它们并不等效。
import pint
ureg = pint.UnitRegistry()
nM = ureg.Unit('nM')
nmol_L = ureg.Unit('nmol/L')
m = ureg.Unit('m')
ft = ureg.Unit('ft')
nM == nmol_L # False
m == ft # False
nM.is_compatible_with(nmol_L) # True
m.is_compatible_with(ft) # True
# What operation does this?
# nM equivalent to nmol # Should be True
# m equivalent to ft # Should be False
一种解决方法是将单位转换为数量,取它们的比率,将其降为基本单位,然后测试数量是否无量纲且其数量等于 1。请注意,由于舍入误差,您不能只这样做常规等于;你需要做一个近似等于,并希望你永远不会遇到任何单位几乎完全相同,但不完全相同。
from math import isclose
import pint
ureg = pint.UnitRegistry()
nM = ureg.Unit('nM')
nmol_L = ureg.Unit('nmol/L')
m = ureg.Unit('m')
ft = ureg.Unit('ft')
def is_equivalent(first: pint.Unit, second: pint.Unit):
ratio = ((1 * first) / (1 * second)).to_base_units()
return ratio.dimensionless and isclose(ratio.magnitude, 1)
is_equivalent(nM, nmol_L) # True
is_equivalent(m, ft) # False
一种解决方法是使用
UnitRegistry.convert(number, current_unit, new_unit)
方法。如果您尝试将 1 从一种单位转换为另一种单位,如果单位相等,结果仍将是 1。如果单位不兼容,它将引发 DimensionalityError
错误。请注意,由于舍入误差,您不能只对 1 执行常规等于;你需要做一个近似等于,并希望你永远不会遇到任何单位几乎完全相同,但不完全相同。
from math import isclose
import pint
ureg = pint.UnitRegistry()
nM = ureg.Unit('nM')
nmol_L = ureg.Unit('nmol/L')
m = ureg.Unit('m')
ft = ureg.Unit('ft')
def is_equivalent(first: pint.Unit, second: pint.Unit):
try:
factor = ureg.convert(1, first, second)
except pint.DimensionalityError:
return False
return isclose(factor, 1)
is_equivalent(nM, nmol_L) # True
is_equivalent(m, ft) # False
请注意,没有记录表明向
pint.Unit
提供 convert
是合法的。
如何简化为基本单位然后进行比较,例如:
import pint
u = pint.UnitRegistry()
u('nM').to_base_units() == u('nmol/L').to_base_units()