[python] 파이썬에서 숫자를 유효 숫자로 반올림하는 방법

UI에 표시하려면 플로트를 반올림해야합니다. 예를 들어, 한 가지 중요한 수치입니다.

1234-> 1000

0.12-> 0.1

0.012-> 0.01

0.062-> 0.06

6253-> 6000

1999-> 2000

파이썬 라이브러리를 사용 하여이 작업을 수행하는 좋은 방법이 있습니까? 아니면 직접 작성해야합니까?



답변

음수를 사용하여 정수를 반올림 할 수 있습니다.

>>> round(1234, -3)
1000.0

따라서 가장 중요한 숫자 만 필요한 경우 :

>>> from math import log10, floor
>>> def round_to_1(x):
...   return round(x, -int(floor(log10(abs(x)))))
...
>>> round_to_1(0.0232)
0.02
>>> round_to_1(1234243)
1000000.0
>>> round_to_1(13)
10.0
>>> round_to_1(4)
4.0
>>> round_to_1(19)
20.0

float가 1보다 큰 경우 float를 정수로 바꾸어야 할 것입니다.


답변

문자열 형식의 % g는 부동 소수점을 몇 개의 유효 숫자로 반올림합니다. 때로는 ‘e’과학 표기법을 사용하므로 둥근 문자열을 다시 float로 변환 한 다음 % s 문자열 형식을 통해 변환하십시오.

>>> '%s' % float('%.1g' % 1234)
'1000'
>>> '%s' % float('%.1g' % 0.12)
'0.1'
>>> '%s' % float('%.1g' % 0.012)
'0.01'
>>> '%s' % float('%.1g' % 0.062)
'0.06'
>>> '%s' % float('%.1g' % 6253)
'6000.0'
>>> '%s' % float('%.1g' % 1999)
'2000.0'


답변

유효 숫자가 1이 아닌 다른 값을 가지려면 (그렇지 않으면 Evgeny와 동일) :

>>> from math import log10, floor
>>> def round_sig(x, sig=2):
...   return round(x, sig-int(floor(log10(abs(x))))-1)
...
>>> round_sig(0.0232)
0.023
>>> round_sig(0.0232, 1)
0.02
>>> round_sig(1234243, 3)
1230000.0


답변

f'{float(f"{i:.1g}"):g}'
# Or with Python <3.6,
'{:g}'.format(float('{:.1g}'.format(i)))

이 솔루션은 다음과 같은 이유로 다른 솔루션과 다릅니다.

  1. 그것은 OP 질문을 정확하게 해결합니다
  2. 추가 패키지 가 필요 하지 않습니다
  3. 사용자 정의 보조 기능 이나 수학 연산이 필요 하지 않습니다

임의 n의 유효 숫자에 대해서는 다음을 사용할 수 있습니다.

print('{:g}'.format(float('{:.{p}g}'.format(i, p=n))))

테스트:

a = [1234, 0.12, 0.012, 0.062, 6253, 1999, -3.14, 0., -48.01, 0.75]
b = ['{:g}'.format(float('{:.1g}'.format(i))) for i in a]
# b == ['1000', '0.1', '0.01', '0.06', '6000', '2000', '-3', '0', '-50', '0.8']

참고 :이 솔루션을 사용하면 후행 0의 숫자가 다른 숫자를 구별하는 표준 방법이 없으므로 입력에서 유효 숫자의 숫자를 동적으로 조정할 수 없습니다 3.14 == 3.1400. 그렇게 하려면 정밀 패키지에 제공된 것과 같은 비표준 기능 이 필요합니다.


답변

원하는 것을 수행하는 정밀 패키지 만들었습니다 . 그것은 당신이 당신의 숫자에 다소 중요한 수치를 줄 수 있습니다.

또한 지정된 유효 숫자로 표준, 과학 및 공학 표기법을 출력합니다.

허용 된 답변에는 선이 있습니다.

>>> round_to_1(1234243)
1000000.0

실제로 8 시그마 무화과를 지정합니다. 숫자 1234243의 경우 내 라이브러리에는 하나의 중요한 그림 만 표시됩니다.

>>> from to_precision import to_precision
>>> to_precision(1234243, 1, 'std')
'1000000'
>>> to_precision(1234243, 1, 'sci')
'1e6'
>>> to_precision(1234243, 1, 'eng')
'1e6'

또한 마지막 유효 숫자를 반올림하고 표기법이 지정되지 않은 경우 사용할 표기법을 자동으로 선택할 수 있습니다.

>>> to_precision(599, 2)
'600'
>>> to_precision(1164, 2)
'1.2e3'


답변

정수를 1의 유효 숫자로 반올림하려면 기본 아이디어는 소수점 앞의 1 자리가있는 부동 소수점으로 변환하고 반올림 한 다음 원래 정수 크기로 다시 변환하는 것입니다.

이를 위해서는 정수보다 10의 가장 큰 거듭 제곱을 알아야합니다. 이를 위해 log 10 기능의 플로어를 사용할 수 있습니다.

from math import log10, floor
def round_int(i,places):
    if i == 0:
        return 0
    isign = i/abs(i)
    i = abs(i)
    if i < 1:
        return 0
    max10exp = floor(log10(i))
    if max10exp+1 < places:
        return i
    sig10pow = 10**(max10exp-places+1)
    floated = i*1.0/sig10pow
    defloated = round(floated)*sig10pow
    return int(defloated*isign)

답변

질문에 직접 대답하기 위해 R 함수의 명명을 사용하는 내 버전은 다음과 같습니다.

import math

def signif(x, digits=6):
    if x == 0 or not math.isfinite(x):
        return x
    digits -= math.ceil(math.log10(abs(x)))
    return round(x, digits)

이 답변을 게시 한 주된 이유는 “0.075”가 0.08이 아니라 0.07로 반올림된다고 불평하는 의견입니다. 이것은 “초보자 C”가 지적한 바와 같이 유한 정밀도와 밑수 -2 표현 을 모두 갖는 부동 소수점 산술의 조합 때문입니다. . 실제로 표현할 수있는 0.075에 가장 가까운 숫자는 약간 작으므로 반올림은 예상과 다르게 나타납니다.

또한 이것은 10 진수가 아닌 부동 소수점 산술의 사용에 적용됩니다 (예 : C와 Java 모두 동일한 문제가 있음).

더 자세하게 보여주기 위해, 파이썬에게 숫자를 “16 진수”형식으로 포맷하도록 요청합니다 :

0.075.hex()

그것은 우리에게 : 0x1.3333333333333p-4. 이 작업을 수행하는 이유는 일반적인 십진수 표현은 반올림을 포함하기 때문에 컴퓨터가 실제로 숫자를 “인식”하는 방식이 아니기 때문입니다. 이 형식에 익숙하지 않은 경우 몇 가지 유용한 참조는 Python 문서C 표준입니다. 입니다.

이 숫자가 어떻게 작동하는지 보여주기 위해 다음을 수행하여 시작점으로 돌아갈 수 있습니다.

0x13333333333333 / 16**13 * 2**-4

인쇄해야합니다 0.075. 16**13소수점 뒤에 13 개의 16 진수가 있기 때문입니다.2**-4 진 지수가 밑이 2이기 때문입니다.

이제 float가 어떻게 표현되는지에 대한 아이디어를 얻었습니다. decimal모듈을 사용하여 좀 더 정밀한 결과를 보여줍니다.

from decimal import Decimal

Decimal(0x13333333333333) / 16**13 / 2**4

제공 : 0.07499999999999999722444243844그리고 왜 round(0.075, 2)평가하는 이유를 희망적으로 설명0.07