Python - Функция для преобразования научной нотации c в префиксы (например, милли, микро) - PullRequest
0 голосов
/ 09 апреля 2020

Я создал функцию, которая преобразует число в научной нотации c в ту, которая использует префиксы, например, где e-3 = m, e3 = k et c

Вот код (I добавьте дополнительные 0 к тем, у которых длина меньше 9 по причинам форматирования):

def convertExpToSI(size):
if (abs(size) >= 1):
    if (abs(size) > 1e+31):
        return "{:.3e}".format(size)
    else:
        for x in [' ', 'K', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y', 'R', 'Q']:
            if abs(size) < 1000.0:
                y = "%3.3f %s" % (size, x)
                if (len(y) == 7):
                    y = '00' + y
                    return y
                elif (len(y) == 8):
                    y = '0' + y
                    return y
                else:
                    return y
            size /= 1000.0

if (abs(size) < 1):
    if (abs(size) < 1e-31):
        return "{:.3e}".format(size)
    else:
        for x in [' ', 'm', 'u', 'n', 'p', 'f', 'a', 'z', 'y', 'r', 'q']:
            if abs(size) > 0.001:
                y = "%3.3f %s" % (size, x)
                if (len(y) == 7):
                    y = '00' + y
                    return y
                elif (len(y) == 8):
                    y = '0' + y
                    return y
                else:
                    return y

            size /= 0.001

И это работает, но в некоторых случаях я чувствую, что это можно улучшить, но мои попытки не увенчались успехом.

В настоящее время с входом print(convertExpToSI(2.855e-06)) вывод 000.003 m.

Но также это можно записать как 2.855 u, что будет лучше, если будет сохранено больше данных.

Что меня больше смущает, так это то, что это работает с числами больше 1. print(convertExpToSI(2.855e+06)) дает 002.855 M, что является правильным и показывает больше данных.

Любая помощь в этом с благодарностью, спасибо!

Ответы [ 2 ]

1 голос
/ 09 апреля 2020

Вы можете использовать словарь для всех диапазонов единиц СИ и разложить отформатированное число в виде строки, чтобы извлечь показатель степени и мантиссу. Диапазон единиц измерения будет равен предыдущему коэффициенту 3 для каждого показателя степени:

units = {  0:' ',
           1:'K',  2:'M',  3:'G',  4:'T',  5:'P',  6:'E',  7:'Z',  8:'Y',  9:'R',  10:'Q',
          -1:'m', -2:'u', -3:'n', -4:'p', -5:'f', -6:'a', -7:'z', -8:'y', -9:'r', -10:'q'
        }

def float2SI(number):
    mantissa,exponent = f"{number:e}".split("e")
    unitRange         = int(exponent)//3                        
    unit              = units.get(unitRange,None)
    unitValue         = float(mantissa)*10**(int(exponent)%3)
    return f"{unitValue:07.3f} {unit}" if unit else f"{number:.5e}"

вывод:

for i in range(-31,34):
        n = 1.23456*10**i
        print(f"{n:e}",float2SI(n))

1.234560e-31 = 1.23456e-31
1.234560e-30 = 001.235 q
1.234560e-29 = 012.346 q
1.234560e-28 = 123.456 q
1.234560e-27 = 001.235 r
1.234560e-26 = 012.346 r
1.234560e-25 = 123.456 r
1.234560e-24 = 001.235 y
1.234560e-23 = 012.346 y
1.234560e-22 = 123.456 y
1.234560e-21 = 001.235 z
1.234560e-20 = 012.346 z
1.234560e-19 = 123.456 z
1.234560e-18 = 001.235 a
1.234560e-17 = 012.346 a
1.234560e-16 = 123.456 a
1.234560e-15 = 001.235 f
1.234560e-14 = 012.346 f
1.234560e-13 = 123.456 f
1.234560e-12 = 001.235 p
1.234560e-11 = 012.346 p
1.234560e-10 = 123.456 p
1.234560e-09 = 001.235 n
1.234560e-08 = 012.346 n
1.234560e-07 = 123.456 n
1.234560e-06 = 001.235 u
1.234560e-05 = 012.346 u
1.234560e-04 = 123.456 u
1.234560e-03 = 001.235 m
1.234560e-02 = 012.346 m
1.234560e-01 = 123.456 m
1.234560e+00 = 001.235  
1.234560e+01 = 012.346  
1.234560e+02 = 123.456  
1.234560e+03 = 001.235 K
1.234560e+04 = 012.346 K
1.234560e+05 = 123.456 K
1.234560e+06 = 001.235 M
1.234560e+07 = 012.346 M
1.234560e+08 = 123.456 M
1.234560e+09 = 001.235 G
1.234560e+10 = 012.346 G
1.234560e+11 = 123.456 G
1.234560e+12 = 001.235 T
1.234560e+13 = 012.346 T
1.234560e+14 = 123.456 T
1.234560e+15 = 001.235 P
1.234560e+16 = 012.346 P
1.234560e+17 = 123.456 P
1.234560e+18 = 001.235 E
1.234560e+19 = 012.346 E
1.234560e+20 = 123.456 E
1.234560e+21 = 001.235 Z
1.234560e+22 = 012.346 Z
1.234560e+23 = 123.456 Z
1.234560e+24 = 001.235 Y
1.234560e+25 = 012.346 Y
1.234560e+26 = 123.456 Y
1.234560e+27 = 001.235 R
1.234560e+28 = 012.346 R
1.234560e+29 = 123.456 R
1.234560e+30 = 001.235 Q
1.234560e+31 = 012.346 Q
1.234560e+32 = 123.456 Q
1.234560e+33 = 1.23456e+33
1 голос
/ 09 апреля 2020

Попробуйте:

    ....
    if (abs(size) < 1):
        if (abs(size) < 1e-31):
            return "{:.3e}".format(size)
        elif (abs(size) > 0.001):
            return "%3.3f" % size
        else:
            for x in [' ', 'm', 'u', 'n', 'p', 'f', 'a', 'z', 'y', 'r', 'q']:
                if abs(size) > 1:
                    y = "%3.3f %s" % (size, x)
                    if (len(y) == 7):
                        y = '00' + y
                        return y
                    elif (len(y) == 8):
                        y = '0' + y
                        return y
                    else:
                        return y

                size /= 0.001

В основном, чтобы сохранить более значимые цифры в случаях, когда размер <1, старайтесь не иметь больше начальных нулей. Для этого вам нужно получить размер> 1, чтобы получить максимально значимые цифры после десятичной точки.

РЕДАКТИРОВАТЬ: Или вы можете поиграть с этим значительным ди git и посмотреть, что подходит вам больше всего. Например, вы также можете попробовать> 0.1 вместо 1.

...