繁体   English   中英

在 Python 中使用工程符号(带有 SI 前缀)将浮点数转换为字符串

[英]Convert float number to string with engineering notation (with SI prefix) in Python

我有一个浮点数,例如x=23392342.1

我想将其转换为带有工程符号的字符串(带有公制前缀)

http://en.wikipedia.org/wiki/Engineering_notation http://en.wikipedia.org/wiki/Metric_prefix

所以在我的例子中 23392342.1 = 23.3923421E6 = 23.3923421 M (mega)

我想显示23.3923421 M

这是一个受Formatting a number with a metric prefix启发的函数

metric.py

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import math


def to_si(d, sep=' '):
    """
    Convert number to string with SI prefix

    :Example:

    >>> to_si(2500.0)
    '2.5 k'

    >>> to_si(2.3E6)
    '2.3 M'

    >>> to_si(2.3E-6)
    '2.3 µ'

    >>> to_si(-2500.0)
    '-2.5 k'

    >>> to_si(0)
    '0'

    """

    inc_prefixes = ['k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y']
    dec_prefixes = ['m', 'µ', 'n', 'p', 'f', 'a', 'z', 'y']

    if d == 0:
        return str(0)

    degree = int(math.floor(math.log10(math.fabs(d)) / 3))

    prefix = ''

    if degree != 0:
        ds = degree / math.fabs(degree)
        if ds == 1:
            if degree - 1 < len(inc_prefixes):
                prefix = inc_prefixes[degree - 1]
            else:
                prefix = inc_prefixes[-1]
                degree = len(inc_prefixes)

        elif ds == -1:
            if -degree - 1 < len(dec_prefixes):
                prefix = dec_prefixes[-degree - 1]
            else:
                prefix = dec_prefixes[-1]
                degree = -len(dec_prefixes)

        scaled = float(d * math.pow(1000, -degree))

        s = "{scaled}{sep}{prefix}".format(scaled=scaled,
                                           sep=sep,
                                           prefix=prefix)

    else:
        s = "{d}".format(d=d)

    return s


if __name__ == "__main__":
    import doctest
    doctest.testmod()

及其用法:

from metric import to_si
d = 23392342.1
print(to_si(d))

它会显示

23.3923421 M

使用QuantiPhy包。 它是一个稳定的有据可查且支持良好的软件包,旨在满足您的需求。

>>> from quantiphy import Quantity

>>> v = Quantity(23.3923421E6)                                               
>>> str(v)                                                                   
'23.392M'                                                                    

>>> v.render(prec='full')                                                    
'23.3923421M'

通常人们使用 SI 单位前缀与单位,而 Quantity 旨在将单位与数字组合。

>>> v = Quantity(23.3923421E6, 'V')
>>> print(v)
23.392 MV

>>> f = Quantity('23.3923421 MHz')
>>> print('{}'.format(f))
23.392 MHz

数量子类是浮动的,因此您可以像使用浮动一样在表达式中使用数量:

>>> t = 1/f                                                                  
>>> print(t)                                                                 
4.274903281275114e-08

>>> t = Quantity(t, 's')                                                     
>>> print(t)
42.749 ns

直接的解决方案是使用Decimal.to_eng_string方法,然后进行字典查找以将指数转换为适当的度量前缀。

您可以使用具有浮点类型和附加格式选项的Prefixed

>>> from prefixed import Float

>>> x = Float(23392342.1)
>>> print(f'{x:!h}')
23.392342 M

或者如果你想保留 7 个小数位

>>> print(f'{x:!.7h}')
23.3923421 M

这是一个没有依赖项的简单方法:

def to_units(x_):
    units = {-12: "T",-9: "G",-6: "M",-3: "K",0: "",3: "m",6: "µ",9: "n",12: "p",15: "f"}
    k = -12
    while x_ * 10.0**k < 1: 
        k += 3
    return f"{x_*10.0**k}{units[k]}"

例子:

for i in range(-15,15):
    print(f"{to_units(1*10.0**i)} \t {1*10.0**i:1,.15f}")

1.0f    0.000000000000001
10.0f   0.000000000000010
100.0f  0.000000000000100
1.0p    0.000000000001000
10.0p   0.000000000010000
100.0p  0.000000000100000
1.0n    0.000000001000000
10.0n   0.000000010000000
100.0n  0.000000100000000
1.0µ    0.000001000000000
10.0µ   0.000010000000000
100.0µ  0.000100000000000
1.0m    0.001000000000000
10.0m   0.010000000000000
100.0m  0.100000000000000
1.0     1.000000000000000
10.0    10.000000000000000
100.0   100.000000000000000
1.0K    1,000.000000000000000
10.0K   10,000.000000000000000
100.0K  100,000.000000000000000
1.0M    1,000,000.000000000000000
10.0M   10,000,000.000000000000000
100.0M  100,000,000.000000000000000
1.0G    1,000,000,000.000000000000000
10.0G   10,000,000,000.000000000000000
100.0G  100,000,000,000.000000000000000
1.0T    1,000,000,000,000.000000000000000
10.0T   10,000,000,000,000.000000000000000
100.0T  100,000,000,000,000.000000000000000

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM