Python을 통해 숫자의 표시 자릿수 지정 - 숫자의 반올림 및 형식 수정 -

제작일자:202409
언어: 파이썬 3

20220427 추기


이 글은 [오류], [추천하지 않는 함수 사용법], [최신 정보가 아님]을 포함하고 있다.평론란에서 다른 사용자에게서 배웠다.깨우쳐 주셔서 감사합니다.
정보를 알고 싶은 사람은 다른 보도나 0을 참조하세요.목적과 배경 - 주석 표시줄 순서대로 읽으세요.2. 결론 아래에 오류가 포함되어 있다.
본래 새로운 정보를 정정하고 가입하는 기사를 내는 것이 최선의 대응책이라고 생각했지만, 다음 작업을 마칠 날이 아직 정해지지 않았기 때문에 긴급히 기사의 첫머리에 방송할 수 있도록 허락해 주십시오.
검색에 방해가 되지 않도록 기사의 내용을 낮추어 (삭제)하는 것도 논의했지만, 받은 댓글은 저에게 매우 계발적인 내용이어서 제 공부를 위해 남겨두고 싶습니다.이렇게 대응(기사를 한정 공유하는 등 검색에 방해가 되지 않도록 기사를 남기는 것이 더 나은 방법이 있을 수 있어 논의를 포함해 추후 대응할 예정)이다.
또 댓글을 달아주신 여러분께 개별적으로 답장과 감사를 드려야 하는데 지금 서둘러 LGTM과 여기서 감사 인사를 드리는 것은 실례입니다.나는 당신이 나에게 알려준 내용을 스스로 조사한 후에 다른 답장을 드리면 좋겠다고 생각합니다.나에게 메시지를 남길 수 있다는 것은 매우 배울 만한 것이다.또 짚고 넘어가야 할 점이 있다면 메시지를 남겨주세요.잘 부탁드립니다.

0. 목적 및 배경


부동 소수점 값을 표시할 때 str型print로만 변환하면 비트가 정렬되지 않습니다.
print_float.py
import numpy as np
for threshold in np.arange(0.1, 0.2, 0.01):
    print('threshold = ' + str(threshold))

# (出力結果)
# threshold = 0.1
# threshold = 0.11
# threshold = 0.12
# threshold = 0.13
# threshold = 0.13999999999999999
# threshold = 0.14999999999999997
# threshold = 0.15999999999999998
# threshold = 0.16999999999999998
# threshold = 0.17999999999999997
# threshold = 0.18999999999999995
인류 측의 희망으로 0.10, 0.11, 0.12, 0.13, 0.14, 0.15, ...였으면 좋겠지만 0.14 이후0.13999999999999999 등으로 나타났다.나는 이것을 0.14로 표시할 방법을 강구하고 싶다.

즉, 하고 싶은 일은

0.13999999999999999← 이건 아니야
0.14← 이렇게 표시하고 싶다
참고로 이'숫자 자릿수가 많고 약간의 편차가 있는 문제'는 컴퓨터가 2진법으로 수치를 표현하기 때문에 발생한 것이다.2진법에서 때로는 10진수를 정확하게 표시할 수 없다. 작은 오차가 생겨서 0.13999999999999999와 같은'약간의 오차의 값'이 된다.그러나 특정 값의 편차가 아닌 컴퓨터에서 값을 올바르게 표시할 수 있는 경우도 있습니다. 예를 들어 0.5는 2의 (-1) 차등(0.5 = 1/2 = 2**(-1)이므로 0.5를 정확하게 나타낼 수 있습니다.
작은 오차를 정확하게 계산하지 않으면 최종 결과에 영향을 미칠 수 있기 때문에 부동점수의 미세한 오차는 그다지 문제가 되지 않기 때문에 나는 지금까지 이 오차를 거의 주의하지 못했다.그러나 수치를 출력할 때0.13999999999999999 등이 적혀 있으면 읽기 어려워 값을 반올림0.14해 표시할 수 있는 방법을 조사했다.

1. 참조 링크


1-1. note.nkmk.me Python으로 소수와 정수를 반올림하는 round와 Decimal.quantize
https://note.nkmk.me/python-round-decimal-quantize/
1-2. note.nkmk.mePython,format 형식으로 변환(0 채우기, 지수 표시, 16진수 등)
https://note.nkmk.me/python-format-zero-hex/

2.결론(바쁜 사람용)


출력 형식을 문자열 방법str.format()으로 지정하면 됩니다.
임의의 자릿수로 값을 지정하고 표시할 수 있습니다.
상세한 상황은 다음과 같다. - 방법2.인용하다
print_float_conclusion.py
import numpy as np
for threshold in np.arange(0.1, 0.2, 0.01):
    print('threshold = {:.2f}'.format(threshold))

# (出力結果)
# 0.10
# 0.11
# 0.12
# 0.13
# 0.14
# 0.15
# 0.16
# 0.17
# 0.18
# 0.19

3. 해결 방법


3 - 방법 1.숫자를 임의의 자릿수로 반올림 후 표시 = 숫자 자체를 출력할 자릿수로 반올림


참조 링크


(재판, 상기 1-1.)
표준 라이브러리decimalquantize() 방법을 사용합니다.
※ 수치의 반올림에도 삽입 함수round()를 사용하는 방법이 있지만, 이번에는 수치의 반올림에 대해 표준 라이브러리decimal를 사용하는 quantize() 방법만 총결산합니다.
사용하지 않는 이유round():
Python 3의 삽입식 함수 round ()의 원환은 일반적인 반올림이 아니라 짝수의 원환 (은행가의 원환) 이다.(중략)...일반적인 반올림이나 소수에 대한 정확한 짝수 반올림을 실현하려면...(중략)...표준 라이브러리decimal의quantize나 새로운 함수를 정의하는 방법을 사용합니다.참조 링크 1-1.
이렇게 round()반올림이 아니라 짝수의 원이 되기 위해서다.

샘플 코드


decimal 모듈 사용
decimal_usage1.py
# Decimal()でDecimal型のオブジェクトを生成できる。 (参考リンク1-1.より引用)
from decimal import Decimal, ROUND_HALF_UP

print(0.05)
# 0.05

print(str(0.05))
# 0.05

# 引数にfloat型を指定すると、実際にどのような値として扱われているかが分かる。(参考リンク1-1.より引用)
print(Decimal(0.05)) 
# 0.05000000000000000277555756156289135105907917022705078125

# float型ではなく文字列str型を指定すると正確にその値のDecimal型として扱われる。(参考リンク1-1.より引用)
print(Decimal(str(0.05))) 
# 0.05
decimal의 반올림 값 사용하기
print_float_decimal.py
import numpy as np
from decimal import Decimal, ROUND_HALF_UP

# for文で指定した数を任意の桁に丸める
for threshold in np.arange(0.1, 0.2, 0.01):
    print(Decimal(str(threshold)).quantize(Decimal('0.01'), rounding=ROUND_HALF_UP))
    # (コードの説明)
    # Decimal(str([float]))でfloat型をdecimal型に変換する。
    # .quantize()メソッドで値の丸めができる。
    # 第一引数に求めたい桁数と同じ桁数の数値を'0.01'のように文字列で指定する。'0'なら整数への丸め。
    # 引数roundingで丸めモードを指定する。ROUND_HALF_UPは四捨五入。

# (出力結果)
# 0.10
# 0.11
# 0.12
# 0.13
# 0.14
# 0.15
# 0.16
# 0.17
# 0.18
# 0.19
참조: 출력 결과 비교
decimal_usage2.py
import numpy as np
from decimal import Decimal, ROUND_HALF_UP

for threshold in np.arange(0.1, 0.2, 0.01):
    print('======')
    print(threshold) #float型
    print(str(threshold)) #str型
    print(Decimal(str(threshold))) #これだと受け取った2進数の桁数を保持したままdecimal型にしてしまう
    print(Decimal(str(threshold)).quantize(Decimal('0.01'), rounding=ROUND_HALF_UP)) #これで値を小数点第2位で丸められた

# (出力結果)
# ======
# 0.1
# 0.1
# 0.1
# 0.10
# ======
# 0.11
# 0.11
# 0.11
# 0.11
# ======
# 0.12
# 0.12
# 0.12
# 0.12
# ======
# 0.13
# 0.13
# 0.13
# 0.13
# ======
# 0.13999999999999999
# 0.13999999999999999
# 0.13999999999999999
# 0.14
# ======
# 0.14999999999999997
# 0.14999999999999997
# 0.14999999999999997
# 0.15
# ======
# 0.15999999999999998
# 0.15999999999999998
# 0.15999999999999998
# 0.16
# ======
# 0.16999999999999998
# 0.16999999999999998
# 0.16999999999999998
# 0.17
# ======
# 0.17999999999999997
# 0.17999999999999997
# 0.17999999999999997
# 0.18
# ======
# 0.18999999999999995
# 0.18999999999999995
# 0.18999999999999995
# 0.19

3 - 방법 2.값 자체는 변하지 않고, 출력할 때 유효한 비트를 지정합니다 = 값 자체는 변하지 않으며, 표시 옵션으로 형식을 지정합니다


참조 링크


(재판, 상기 1-2.)
내장 함수format()나 문자열 방법str.format()을 사용합니다.문자열 방법 str.format() 을 사용합니다.str.format()소수점 이하의 자릿수를 지정하려면 을 선택합니다.[자릿수]f로 설정합니다.소수점 이하는 정수 부분의 자릿수에 관계없이 지정된 자릿수입니다.참조 링크 1-2.

샘플 코드


문자열 방법str.format()의 사용 방법1
print_float_format1.py
import numpy as np
for threshold in np.arange(0.1, 0.2, 0.01): 
    print('{:.2f}'.format(threshold)) #{}内がformat()の引数の書式の指定

# (出力結果)
# 0.10
# 0.11
# 0.12
# 0.13
# 0.14
# 0.15
# 0.16
# 0.17
# 0.18
# 0.19
문자열 방법str.format()의 사용 방법2
print_float_format2.py
import numpy as np
for threshold in np.arange(0.1, 0.2, 0.01): 
    print('threshold = {:.2f}'.format(threshold))
    #上のように、「他の(任意の)文字列」と「書式を指定して代入する文字列」を組み合わせることもできる。

# (出力結果)
# threshold=0.10
# threshold=0.11
# threshold=0.12
# threshold=0.13
# threshold=0.14
# threshold=0.15
# threshold=0.16
# threshold=0.17
# threshold=0.18
# threshold=0.19
삽입 함수format()와 문자열 방법str.format()도 여러 문자열을 대입할 형식을 지정할 수 있습니다.(자세한 내용은 참조 링크 1-2.
str.format() 방법의 사용 예str.format()의 반환값은 문자열입니다
"This is a string"
동일 문자열.
예를 들어 도표 제목에 수치를 넣는 경우 등에 사용할 수 있다.
print_format_graphTitle.py
import numpy as np
for threshold in np.arange(0.1, 0.2, 0.01): 
    plt.figure()
    plt.imshow(np.zeros([512,512]), cmap='gray') # 例示のために、黒い正方形を描画
    plt.axis('off')
    plt.title('threshold = {:.2f}'.format(threshold))
    plt.show()
출력 결과는 threshold = 0.13999999999999999일 때 다음과 같습니다.
명확하게 나타낼 수 있다0.14.

보충으로 삼다
# 上記のように、グラフタイトルに数値を入れたいような場合に、

plt.title('threshold = {:.2f}'.format(threshold))
# の代わりに

plt.title('threshold = ' + str(threshold))
# のように書くと、0.14と表示されてほしいところが0.13999999999999999と桁が多くなったり、

plt.title('threshold = ' + str(Decimal(str(threshold)).quantize(Decimal('0.01'), rounding=ROUND_HALF_UP)))
# のように書くと、長くて読みにくくなったりするので、
# str.format()メソッドで簡単に書式を変更できるのはとても便利だと感じた。
끝맺다

좋은 웹페이지 즐겨찾기