打印浮点值时如何抑制科学计数法?
- 2024-12-12 08:41:00
- admin 原创
- 131
问题描述:
这是我的代码:
x = 1.0
y = 100000.0
print x/y
我的商显示为1.00000e-05
。
有什么方法可以抑制科学计数法并使其显示为0.00001
?我将使用字符串作为结果。
解决方案 1:
使用较新的版本''.format
(还要记得指定.
要显示的后面的几位数字,这取决于浮点数有多小)。请参见以下示例:
>>> a = -7.1855143557448603e-17
>>> '{:f}'.format(a)
'-0.000000'
如上所示,默认值为 6 位数字!这对于我们的案例没有帮助,因此我们可以使用类似以下内容:
>>> '{:.20f}'.format(a)
'-0.00000000000000007186'
更新
从 Python 3.6 开始,可以使用新的格式化字符串文字来简化此操作,如下所示:
>>> f'{a:.20f}'
'-0.00000000000000007186'
解决方案 2:
'%f' % (x/y)
但你需要自己管理精度。例如,
'%f' % (1/10**8)
仅显示零。
详细信息请参阅文档
或者对于 Python 3,等效的旧格式或较新的样式格式
解决方案 3:
另一个选择是,如果您正在使用 pandas 并且想要抑制所有浮点数的科学计数法,则可以调整 pandas 选项。
import pandas as pd
pd.options.display.float_format = '{:.2f}'.format
解决方案 4:
上面的大多数答案都要求您指定精度。但是,如果您想像这样显示浮点数,而没有不必要的零,该怎么办:
1
0.1
0.01
0.001
0.0001
0.00001
0.000001
0.000000000001
numpy
有答案:np.format_float_positional
import numpy as np
def format_float(num):
return np.format_float_positional(num, trim='-')
解决方案 5:
使用较新版本的 Python(2.6 及更高版本),您可以使用它''.format()
来完成@SilentGhost 建议的操作:
'{0:f}'.format(x/y)
由于PEP-498已有 8 年历史,因此 Python 3.6 及更高版本支持:
f'{x/y:f}'
有人对打印列表发表了评论,因此这里有一条额外的 1 行代码:
[f'{x:f}' for x in long_list]
解决方案 6:
对于 numpy 数组,你可以使用 suppress 命令进行抑制,如下所示
import numpy as np
np.set_printoptions(suppress=True)
解决方案 7:
您可以使用内置format
函数。
>>> a = -3.42142141234123e-15
>>> format(a, 'f')
'-0.000000'
>>> format(a, '.50f') # Or you can specify precision
'-0.00000000000000342142141234122994048466990874926279'
解决方案 8:
这对于任何指数都有效:
def getExpandedScientificNotation(flt):
str_vals = str(flt).split('e')
coef = float(str_vals[0])
exp = int(str_vals[1])
return_val = ''
if int(exp) > 0:
return_val += str(coef).replace('.', '')
return_val += ''.join(['0' for _ in range(0, abs(exp - len(str(coef).split('.')[1])))])
elif int(exp) < 0:
return_val += '0.'
return_val += ''.join(['0' for _ in range(0, abs(exp) - 1)])
return_val += str(coef).replace('.', '')
return return_val
解决方案 9:
这是使用Captain Cucumber 的答案,但添加了 2 点。
1)允许函数获取非科学计数法数字并按原样返回它们(因此您可以输入大量数据,其中一些数字是 0.00003123 与 3.123e-05,并且函数仍然可以工作。
2) 增加了对负数的支持。(在原始函数中,负数最终会变成 0.0000-108904,而不是 -1.08904e-05)
def getExpandedScientificNotation(flt):
was_neg = False
if not ("e" in flt):
return flt
if flt.startswith('-'):
flt = flt[1:]
was_neg = True
str_vals = str(flt).split('e')
coef = float(str_vals[0])
exp = int(str_vals[1])
return_val = ''
if int(exp) > 0:
return_val += str(coef).replace('.', '')
return_val += ''.join(['0' for _ in range(0, abs(exp - len(str(coef).split('.')[1])))])
elif int(exp) < 0:
return_val += '0.'
return_val += ''.join(['0' for _ in range(0, abs(exp) - 1)])
return_val += str(coef).replace('.', '')
if was_neg:
return_val='-'+return_val
return return_val
解决方案 10:
所有其他答案都有效,但有一个缺陷:小数位数会改变(增加或减少)
这是一个可行的解决方案,并且不会改变您的数字的精度。
from decimal import Decimal
number = Decimal('0.000000001')
# f-string
f'{number:.{abs(number.as_tuple().exponent)}f}'
# or format
format(number, '.{0}f'.format(abs(number.as_tuple().exponent)))
您可以创建一个类,例如
class FormatedDecimal(Decimal):
def __str__(self):
return f'{self:.{abs(self.as_tuple().exponent)}f}'
并会给你:
>>> str(FormatedDecimal(100000))
'100000'
>>> str(FormatedDecimal('10000.0'))
'10000.0'
>>> str(FormatedDecimal('0.0000000001'))
'0.0000000001'
>>> str(FormatedDecimal('1.00000000000000000001'))
'1.00000000000000000001'
>>> str(FormatedDecimal('0.0000000000000'))
'0.0000000000000'
>>> str(FormatedDecimal('0.0000000000000'))
'0.0000000000000'
>>> str(FormatedDecimal('1.48e-9'))
'0.00000000148'
解决方案 11:
由于这是 Google 上的最佳结果,在未能找到问题解决方案后,我将在此发布。如果您希望格式化浮点对象的显示值并使其保持为浮点数(而不是字符串),则可以使用此解决方案:
创建一个新类来修改浮点值的显示方式。
from builtins import float
class FormattedFloat(float):
def __str__(self):
return "{:.10f}".format(self).rstrip('0')
您可以通过更改整数值来自己修改精度{:f}
解决方案 12:
如果是,string
则使用其内置功能float
进行转换,例如:print( "%.5f" % float("1.43572e-03"))
答案:0.00143572
解决方案 13:
一种更简单的解决方案,可将浮点数显示为任意数量的有效数字。numpy
这里不需要或列表理解:
def sig(num, digits=3):
"Return number formatted for significant digits"
if num == 0:
return 0
negative = '-' if num < 0 else ''
num = abs(float(num))
power = math.log(num, 10)
if num < 1:
step = int(10**(-int(power) + digits) * num)
return negative + '0.' + '0' * -int(power) + str(int(step)).rstrip('0')
elif power < digits - 1:
return negative + ('{0:.' + str(digits) + 'g}').format(num)
else:
return negative + str(int(num))
我在示例中删除了尾随的 0 并显示完整的整数:sig(31415.9) = 31415
而不是 31400。如果您不喜欢,请随意修改代码。
测试:
for power in range(-8,8):
num = math.pi * 10**power
print(str(num).ljust(25), sig(num))
解决方案 14:
除了SG的答案之外,您还可以使用Decimal模块:
from decimal import Decimal
x = str(Decimal(1) / Decimal(10000))
# x is a string '0.0001'
解决方案 15:
使用 3.6.4 时,我遇到了类似的问题,即使用以下命令时,输出文件中的数字会随机地被格式化为科学计数法:
fout.write('someFloats: {0:0.8},{1:0.8},{2:0.8}'.format(someFloat[0], someFloat[1], someFloat[2]))
我所需要做的就是添加“f”来修复它:
fout.write('someFloats: {0:0.8f},{1:0.8f},{2:0.8f}'.format(someFloat[0], someFloat[1], someFloat[2]))
解决方案 16:
从 3.6 开始(可能也适用于稍旧的 3.x),这是我的解决方案:
import locale
locale.setlocale(locale.LC_ALL, '')
def number_format(n, dec_precision=4):
precision = len(str(round(n))) + dec_precision
return format(float(n), f'.{precision}n')
计算的目的precision
是确保我们有足够的精度以避免科学计数法(默认精度仍然为 6)。
该dec_precision
参数增加了用于小数点的额外精度。由于这利用了n
格式,因此不会添加无关紧要的零(与f
格式不同)。n
还将负责呈现没有小数的整数。
n
确实需要float
输入,因此需要演员。
解决方案 17:
我遇到了类似的问题,使用我的解决方案:
from decimal import Decimal
Decimal(2/25500)
#output:0.00007843137254901961000728982664753630160703323781490325927734375