簡體   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