简体   繁体   English

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

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

I have a float number such as x=23392342.1我有一个浮点数,例如x=23392342.1

I would like to convert it to a string with engineering notation (with metric prefix)我想将其转换为带有工程符号的字符串(带有公制前缀)

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

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

I would like to display 23.3923421 M我想显示23.3923421 M

Here is a function inspired from Formatting a number with a metric prefix?这是一个受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()

and its usage:及其用法:

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

It will display它会显示

23.3923421 M

Use the QuantiPhy package.使用QuantiPhy包。 It is a stable well documented and well supported package that is designed to do just what you want.它是一个稳定的有据可查且支持良好的软件包,旨在满足您的需求。

>>> from quantiphy import Quantity

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

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

Generally people use SI unit prefixes with units, and Quantity is designed to combine the units with the number.通常人们使用 SI 单位前缀与单位,而 Quantity 旨在将单位与数字组合。

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

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

Quantity subclasses float, so you can use quantities in expressions as you would a float:数量子类是浮动的,因此您可以像使用浮动一样在表达式中使用数量:

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

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

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

You can use Prefixed which has a float type with additional formatting options.您可以使用具有浮点类型和附加格式选项的Prefixed

>>> from prefixed import Float

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

Or if you want to keep 7 decimal places或者如果你想保留 7 个小数位

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

This is a simple method with no dependencies:这是一个没有依赖项的简单方法:

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]}"

Example:例子:

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