可以使用Python 3的数字格式

时间:2016-03-11 17:55:15

标签: python python-3.x matplotlib formatting seaborn

特定问题

我正在尝试打印seaborn热图中单元格顶部的数字。例如,像:

ax = sns.heatmap(flights, annot=True, fmt=",")

(这是直接来自seaborn's documentation,调整为Python 3友好。所以如果你导入seaborn,你可以开箱即用同样的例子。)

这会产生一个相当可观的数字,如下图所示:

heatmap, not quite ideal

但是,我希望看到数字四舍五入到最近的 数百 。换句话说,我希望看到171写成200的数字,315写成300等等。

在幕后,seaborn实际上只是matplotlib。我可以使用matplotlib' s text methods

matplotlib的文字依赖于Python 3的text formatting,它有方便的方法将 舍入到小数点右侧 ,通过像.2这样的事情来回到百分之百***,但我找不到任何东西来向另一个方向转。

在我将它们推送到情节之前,我可以简单地对数字进行舍入,但这实际上会改变情节数据本身,我宁愿避免。因此,我希望将 底层数字保留在未经更改的情节 中,同时仍然能够很好地打印出来。

据我所知,唯一的办法就是找到一种巧妙的格式化方法。有办法吗?

谢谢!

更新

我进一步挖掘seaborn's code,试图理解为什么La Rooy的巧妙解决方案不适合我。

seaborn代码中的相关行是:

val = ("{:" + self.fmt + "}").format(val)

但是,为了实现这一点,我需要能够更改我的pandas数据框列,这意味着我需要能够调整nd.array元素的列

似乎有not yet any underlying .__format__ method for a numpy array,但我们努力创建一个。

所以,我现在不再追问这个问题了,并希望一旦事情解决了,我就能够采取La Rooy的解决方案,事情应该&&&今天应该& #34;工作"

一旦发生这种情况,解决方案将是:

>>> class rndarray(np.ndarray):
...     def __format__(self, spec):
...         return np.ndarray.__format__(int(round(self, -2)), spec)
... 
>>> df['<col_of_interest>'] = map(rndarray, df['<col_of_interest.'])

或者,如果那不起作用,那么:

>>> df['<col_of_interest>'].values = map(rndarray, df['<col_of_interest.'].values)

2 个答案:

答案 0 :(得分:2)

您可以使用int的子类,并根据需要定义__format__

>>> class rint(int):
...     def __format__(self, spec):
...         return int.__format__(int(round(self, -2)), spec)
... 
>>> raw_data = [111, 22222, 33333]
>>> data = map(rint, raw_data)
>>> [format(x, ',') for x in data]
['100', '22,200', '33,300']

或等效于花车

>>> class rfloat(float):
...     def __format__(self, spec):
...         return float.__format__(round(self, -2), spec)
... 
>>> raw_data = [111.11, 22222.22, 33333.33]
>>> data = map(rfloat, raw_data)
>>> spec = ',.0f'
>>> [format(x, spec) for x in data]
['100', '22,200', '33,300']

编辑: 这个更hacky的解决方案利用val = ("{:" + self.fmt + "}").format(val)行。当然,如果实施改变,这可能会中断。

class Fmt(str):
    def __add__(self, other):
        return Fmt(str.__add__(self, other))
    def __radd__(self, other):
        return Fmt(str.__add__(other, self))
    def format(self, *args):
        return str.format(self, *(int(round(x, -2)) for x in args))

ax = sns.heatmap(flights, annot=True, fmt=Fmt(","))

最好能够传递Formatter()而不是fmt字符串。

答案 1 :(得分:1)

确实

'{:.0f}00'.format(yourNumber / 100.0)

每个细胞解决您的问题?