HOWTO · Python
Python에서 숫자를 유효 숫자로 반올림하는 방법
round(), math, 서식 지정, Decimal, sigfig, NumPy를 사용하여 Python 숫자를 유효 숫자로 반올림하는 방법을 알아보세요.
이 페이지의 내용
숫자를 선택한 유효 숫자 자릿수로 반올림하려면, 십진 크기를 구하고 해당하는 소수 자릿수를 round()에 전달하세요. 예를 들어, 1,342를 유효 숫자 한 자리로 반올림하면 1,000이 됩니다. 단일 값에는 내장 함수로 충분합니다. 반복 계산에는 헬퍼를, 결과가 텍스트로 유지되어야 할 때는 서식 지정을, 십진 반올림 규칙이 중요할 때는 Decimal을, 배열에는 NumPy를 사용하세요.
Python’s round()로 유효 숫자로 반올림하기
round(number, ndigits)는 소수 자릿수까지 반올림합니다. 유효 숫자의 경우 ndigits를 digits - 1 - floor(log10(abs(number)))로 계산합니다. 1,342와 유효 숫자 한 자리의 경우 이는 1 - 1 - 3, 즉 -3이므로 Python은 가장 가까운 천 단위로 반올림합니다.
이 예제를 실행하세요.
print(round(1342, -3))
1000
Python은 중간값인 경우 짝수로 반올림(ties-to-even)을 사용하므로, 값이 두 반올림된 값의 정확히 중간에 있을 때 마지막으로 유지되는 자릿수는 짝수가 됩니다. 이는 중간값인 경우 항상 0에서 멀어지는 방향으로 반올림하는 것과 다릅니다. 음수 ndigits는 십, 백 또는 더 큰 10의 거듭제곱으로 반올림합니다. round()는 숫자를 반환합니다. 뒤에 붙는 0을 표시 관례로 유지하지 않습니다. 부동 소수점 입력의 경우 저장된 이진 근사값도 겉보기 십진 중간값에 영향을 줄 수 있습니다.
math 헬퍼로 유효 숫자로 반올림하기
헬퍼는 10을 밑으로 하는 크기에서 소수 자릿수를 계산할 수 있습니다. 다음 버전은 양의 정수 자릿수와 유한한 숫자 값을 허용하고, 0은 그대로 반환합니다. 지원되지 않는 자릿수나 유한하지 않은 입력에 대해서는 ValueError를 발생시킵니다. log10()가 해당 값들에 대해 유한한 십진 크기를 결정할 수 없기 때문입니다.
from math import floor, isfinite, log10
def round_significant(value, digits):
if not isinstance(digits, int) or digits < 1:
raise ValueError("digits must be a positive integer")
if not isfinite(value):
raise ValueError("value must be finite")
if value == 0:
return value
places = digits - 1 - floor(log10(abs(value)))
return round(value, places)
print(round_significant(1324, 2))
이 공식은 abs(value)를 사용하여 크기를 구하고, round()가 부호를 유지하므로 양의 유한 값과 음의 유한 값 모두에서 동작합니다. Python의 짝수로 반올림 규칙을 따릅니다. 로그를 계산하기 전에 입력이 지원되는지 결정하려면 math.isfinite()를 사용하세요. 애플리케이션에서 필요하다면 NaN과 무한대를 별도로 처리하세요.
문자열 서식 지정으로 유효 숫자로 반올림하기
%g 서식은 정밀도를 유효 숫자 자릿수로 사용합니다. 정밀도 p인 경우, 십진 지수가 -4보다 작거나 p보다 크거나 같으면 과학적 표기법을 사용하고, 그렇지 않으면 일반 표기법을 사용합니다. 정밀도 3의 경우 0.0001과 999는 일반 표기법을 사용하고, 0.00001과 1000은 과학적 표기법을 사용합니다. 서식 지정은 문자열을 반환하므로, 목표가 표현일 때 유용합니다. 선택한 표현을 유지하려면 그 문자열을 그대로 두세요. 나중에 숫자 연산이 필요할 때만 float()로 변환하세요. 숫자로 변환하면 뒤에 붙는 0과 같은 표시 세부 사항이 사라집니다.
예를 들어, "%.3g" % 1324는 값을 유효 숫자 세 자리로 서식 지정합니다. 결과는 텍스트이며, 일반 표기법과 과학적 표기법 사이의 정확한 선택은 포맷터가 수행합니다.
sigfig로 유효 숫자로 반올림하기
타사 패키지 sigfig는 sigfigs 인수를 통해 유효 숫자의 개수를 허용합니다. 사용하기 전에 환경에 패키지를 설치하세요. 예를 들어, 패키지 호출은 sigfig.round(1324, sigfigs=2)입니다. 이는 패키지의 동작과 서식 지정이 애플리케이션에 적합할 때 편리합니다. 위의 내장 또는 헬퍼 접근 방식에는 필요하지 않습니다.
decimal.Decimal로 유효 숫자로 반올림하기
Decimal은 십진 연산과 명시적인 반올림 모드를 지원합니다. 입력의 십진 숫자가 중요할 때는 문자열에서 이를 구성하세요. 기존 float를 변환해도 float가 저장하지 않은 정보를 복구할 수는 없습니다. 이 예제는 유한하고 0이 아닌 십진수를 요청된 정밀도로 조정하고, ROUND_HALF_UP로 중간값을 0에서 멀어지는 방향으로 반올림합니다.
from decimal import Decimal, ROUND_HALF_UP
def round_decimal_significant(value, digits):
if not isinstance(digits, int) or digits < 1:
raise ValueError("digits must be a positive integer")
number = Decimal(str(value))
if not number.is_finite():
raise ValueError("value must be finite")
if number.is_zero():
return number
quantum = Decimal(1).scaleb(number.adjusted() - digits + 1)
return number.quantize(quantum, rounding=ROUND_HALF_UP)
print(round_decimal_significant("1324", 2))
결과는 Decimal로 유지됩니다. ROUND_HALF_UP는 하나의 정책일 뿐입니다. 애플리케이션의 규칙과 일치할 때 ROUND_HALF_EVEN과 같은 모드를 선택하세요. 십진 연산은 여전히 활성 컨텍스트 정밀도에 의해 제한될 수 있으므로, 무제한 정밀도를 약속하지는 않습니다.
NumPy로 배열을 유효 숫자로 반올림하기
NumPy는 입력이 배열일 때 유용하지만, numpy.around()는 유효 숫자가 아닌 소수 자릿수를 허용합니다. 유한하고 0이 아닌 값의 경우 digits - 1 - floor(log10(abs(value)))로 소수 자릿수를 계산하여 numpy.around()에 전달하세요. 배열의 경우 요소별로 크기를 계산하고, 로그를 취하기 전에 0과 유한하지 않은 값을 처리하세요. NumPy는 추가 종속성입니다. 이 접근 방식은 부동 소수점 반올림 동작을 따르며 표시용 0을 유지하지 않습니다.
아래 예제는 유한하고 0이 아닌 요소만 반올림합니다. 0, NaN, 양의 무한대 또는 음의 무한대는 그대로 둡니다. 반환 값은 부동 소수점 요소를 가진 NumPy ndarray입니다. NumPy는 추가 종속성이므로 이 예제를 실행하기 전에 설치하세요.
import numpy as np
values = np.array([1234.5, -1234.5, 0.0, np.nan, np.inf, -np.inf])
digits = 3
rounded = values.copy()
finite_nonzero = np.isfinite(values) & (values != 0)
for index in np.flatnonzero(finite_nonzero):
places = digits - 1 - int(np.floor(np.log10(abs(values[index]))))
rounded[index] = np.around(values[index], decimals=places)
print(rounded.tolist())
[1230.0, -1230.0, 0.0, nan, inf, -inf]