下面是格式化我一直使用的x值的代码。
它的作用示例:
它将800,000格式化为800 K It
def Formatting(self, x, pos):
formats = ((1e-12,'%d%s T','%1.1f T'),
(1e-9, '%d%s B','%1.1f B'),
(1e-6, '%d%s M','%1.1f M'),
(1e-3, '%d%s k','%1.1f K' ))
for i, (N, A, B) in enumerate(formats):
if abs(x) > (1./N):
result = ''
x = x * N
if abs(x) >= 1000:
x, r = divmod(x, 1000)
result = ",%03d%s" % (r, result)
return A % (x, result)
else: return B % (x)
elif 1 <= abs(x) < 1e3: return '%1.0f' % (x)
elif 0.1 <= abs(x) < 1: return '%1.1f' % (x)
elif 0 < abs(x) < 0.1: return '%1.3f' % (x)
elif x == 0: return '%1.0f' % (x)
现在,我一直在努力对其进行以下改进:
有关如何执行此更改或改进此代码以获得更多含义的打印输出(在图表中使用)的建议?
非常感谢!
答案 0 :(得分:4)
生成格式字符串的方法可能更短;但它们很容易只能映射到每个量级。我不完全理解你想要的行为w / r / t小数点长度,但这个逻辑应该很容易。
因为你所拥有的是一种方法,所以我将它合并到一个类中。 (这也避免了每次调用函数时都定义formats
。)
from math import log10
class Formatter(object):
def __init__(self):
self.formats = (('%1.1f', 0),
('%2.1f', 0),
('%1.2f K', 3),
('%1.2f K', 3),
('%2.1f K', 3),
('%1.2f M', 6),
('%1.2f M', 6),
('%2.1f M', 6),
('%1.2f B', 9),
('%1.2f B', 9),
('%2.1f B', 9),
('%1.2f T', 12),
('%1.2f T', 12),
('%2.1f T', 12))
def human_readable(self, x):
if x == 0: return '0'
magnitude = int(log10(abs(x)))
if magnitude > 13: format_str, denominator_mag = '%i T', 12
else: format_str, denominator_mag = self.formats[magnitude]
return (format_str % (x * 1.0 / (10 ** denominator_mag))).lstrip('0')
编辑:这是一个不使用查找表的内容:
def human_readable(self, x):
if x == 0: return '0'
magnitude = int(log10(abs(x)))
if magnitude > 13:
format_str = '%i T'
denominator_mag = 12
else:
float_fmt = '%2.1f ' if magnitude % 3 == 1 else '%1.2f '
illion = (magnitude + 1) // 3
format_str = float_fmt + ['', 'K', 'M', 'B', 'T'][illion]
denominator_mag = illion * 3
return (format_str % (x * 1.0 / (10 ** denominator_mag))).lstrip('0')
答案 1 :(得分:0)
尝试所有不同的可能方式对其进行格式化并选择最短的长度方式,优先考虑更大的单位(例如,更喜欢.55 B到550 M,因为它们的长度相同)。
对于剥离前导零,一种可能的解决方案是检查是s[:2] == '0.'
并将其替换为'.'