【问题标题】:How to define and use percentage in Pint如何在 Pint 中定义和使用百分比
【发布时间】:2017-01-02 09:27:01
【问题描述】:

我目前正在使用Pint 来处理单位和单位转换。这似乎适用于已经在 Pint 中定义的单位,例如

>>> import pint
>>> ureg = pint.UnitRegistry()
>>> Q = ureg.Quantity
>>> a = Q(5, 'm/s')
>>> a
<Quantity(5, 'meter / second')>
>>> a.to('ft/s')
<Quantity(16.404199475065617, 'foot / second')>

我尝试define my own units,代表百分比。就单位转换而言,百分比只是无量纲分数的 100 倍,这就是我的定义。

>>> ureg.define('percent = dimensionless * 100 = pct')
>>> a = Q(5, 'pct')
>>> a
<Quantity(5, 'percent')>

但是我似乎无法在分数 ('dimensionless') 和 'pct' 之间来回转换。

>>> a.to('dimensionless')
Traceback (most recent call last):
  File "<pyshell#31>", line 1, in <module>
    a.to('dimensionless')
  File "C:\Python35\python-3.5.1.amd64\lib\site-packages\pint\quantity.py", line 263, in to
    magnitude = self._convert_magnitude_not_inplace(other, *contexts, **ctx_kwargs)
  File "C:\Python35\python-3.5.1.amd64\lib\site-packages\pint\quantity.py", line 231, in _convert_magnitude_not_inplace
    return self._REGISTRY.convert(self._magnitude, self._units, other)
  File "C:\Python35\python-3.5.1.amd64\lib\site-packages\pint\unit.py", line 1026, in convert
    return self._convert(value, src, dst, inplace)
  File "C:\Python35\python-3.5.1.amd64\lib\site-packages\pint\unit.py", line 1042, in _convert
    src_dim = self._get_dimensionality(src)
  File "C:\Python35\python-3.5.1.amd64\lib\site-packages\pint\unit.py", line 813, in _get_dimensionality
    self._get_dimensionality_recurse(input_units, 1.0, accumulator)
  File "C:\Python35\python-3.5.1.amd64\lib\site-packages\pint\unit.py", line 837, in _get_dimensionality_recurse
    self._get_dimensionality_recurse(reg.reference, exp2, accumulator)
  File "C:\Python35\python-3.5.1.amd64\lib\site-packages\pint\unit.py", line 835, in _get_dimensionality_recurse
    reg = self._units[self.get_name(key)]
KeyError: ''

我基本上想做的是能够在例如“0.73”和“73%”。如何定义和使用这样的单位?

【问题讨论】:

    标签: python units-of-measurement pint


    【解决方案1】:

    似乎 GitHub 问题 hgrecco/pint#185 涵盖了您所描述的情况。

    使用Pint-0.7.2 对我来说,使用该问题中讨论的解决方法:

    from pint.unit import ScaleConverter
    from pint.unit import UnitDefinition
    import pint
    
    ureg = pint.UnitRegistry()
    Q = ureg.Quantity
    
    ureg.define(UnitDefinition('percent', 'pct', (), ScaleConverter(1 / 100.0)))
    a = Q(5, 'pct')
    
    print a
    print a.to('dimensionless')
    

    输出:

    5 percent
    0.05 dimensionless
    

    【讨论】:

    • 我用过from pint.converters import ScaleConverter
    • 从 pint 0.8 开始,他们似乎已经删除了 pint.unit.ScaleConverter,尽管 pint.converters.ScaleConverter 仍然可用,所以解决方案的其余部分仍然有效。
    • 在 pint 0.9 中,这可以通过首先定义一个单位 ureg.define('fraction = []') 来完成,然后可以使用它而不是直接使用 dimensionless 来定义缩放版本。详情请见my answer
    【解决方案2】:

    我遇到了同样的问题,并想出了一个简单的解决方案,似乎效果很好。

    import pint
    
    ureg = pint.UnitRegistry()
    ureg.define('fraction = [] = frac')
    ureg.define('percent = 1e-2 frac = pct')
    ureg.define('ppm = 1e-6 fraction')
    
    print(ureg('100 pct').to('dimensionless'))
    print(ureg('0.5 dimensionless').to('pct'))
    print(ureg('pct').to('ppm'))
    print(ureg('1e4 ppm').to('pct'))
    

    输出:

    1.0 dimensionless
    50.0 percent
    10000.0 ppm
    0.9999999999999999 percent
    

    (注意最后一行有轻微的舍入误差。)

    我从默认的units dictionary 获得语法,其中基本单位的定义如下

    # reference
    gram = [mass] = g  # dimensional
    radian = [] = rad  # dimensionless
    

    【讨论】:

    • 两种解决方案略有不同:调用to_base_units()时,您的解决方案解析为fraction,而另一个解决方案解析为dimensionless
    猜你喜欢
    • 1970-01-01
    • 2013-10-10
    • 1970-01-01
    • 2021-08-19
    • 1970-01-01
    • 2011-07-14
    • 2011-02-15
    • 1970-01-01
    • 2022-11-15
    相关资源
    最近更新 更多