格式化熊猫数据框中整数的千位分隔符

Posted

技术标签:

【中文标题】格式化熊猫数据框中整数的千位分隔符【英文标题】:Formatting thousand separator for integers in a pandas dataframe 【发布时间】:2014-07-23 23:17:18 【问题描述】:

我正在尝试使用':,'.format(number) 像下面的示例来格式化熊猫数据框中的数字:

# This works for floats and integers
print ':,'.format(20000)
# 20,000
print ':,'.format(20000.0)
# 20,000.0

问题在于,具有整数的数据帧不起作用,而具有浮点数的数据帧可以正常工作。查看示例:

# Does not work. The format stays the same, does not show thousands separator
df_int = DataFrame("A": [20000, 10000])
print df_int.to_html(float_format=lambda x: ':,'.format(x))

# Example of result
# <tr>
#   <th>0</th>
#   <td> 20000</td>
# </tr

# Works OK
df_float = DataFrame("A": [20000.0, 10000.0])
print df_float.to_html(float_format=lambda x: ':,'.format(x))

# Example of result
# <tr>
#   <th>0</th>
#   <td>20,000.0</td>
# </tr>

我做错了什么?

【问题讨论】:

我不知道为什么它不适用于整数,但你不能使用浮点数并指定精度,如:,.0f 你需要为int指定一个单独的格式化程序;例如,请参阅this 问题。 但在那个问题中,他使用了与我使用的相同格式int_frmt = lambda x: ':,'.format( x ) 【参考方案1】:

pandas(从 0.20.1 开始)不允许以简单的方式覆盖默认整数格式。它被硬编码在pandas.io.formats.format.IntArrayFormatterlabmda 函数)中:

class IntArrayFormatter(GenericArrayFormatter):

    def _format_strings(self):
        formatter = self.formatter or (lambda x: '% d' % x)
        fmt_values = [formatter(x) for x in self.values]
        return fmt_values

我假设您实际要求的是如何覆盖 所有整数的格式:替换(“猴子补丁”)IntArrayFormatter 以打印数千个整数值用逗号分隔如下:

import pandas

class _IntArrayFormatter(pandas.io.formats.format.GenericArrayFormatter):

    def _format_strings(self):
        formatter = self.formatter or (lambda x: ' :,'.format(x))
        fmt_values = [formatter(x) for x in self.values]
        return fmt_values

pandas.io.formats.format.IntArrayFormatter = _IntArrayFormatter

注意:

在 0.20.0 之前,格式化程序位于 pandas.formats.format。 在 0.18.1 之前,格式化程序位于 pandas.core.format

一边

对于花车,你不需要跳过那些圈,因为它有一个configuration option:

display.float_format:可调用对象应接受浮点数并返回具有所需数字格式的字符串。这在某些地方使用,例如SeriesFormatter。示例见core.format.EngFormatter

【讨论】:

【参考方案2】:

to_html 中的formatters 参数将采用映射到格式化函数的列名字典。下面有一个函数示例,用于构建将相同函数映射到浮点数和整数的 dict。

In [250]: num_format = lambda x: ':,'.format(x)

In [246]: def build_formatters(df, format):
     ...:     return column:format 
     ...:               for (column, dtype) in df.dtypes.iteritems()
     ...:               if dtype in [np.dtype('int64'), np.dtype('float64')]
     ...: 

In [247]: formatters = build_formatters(df_int, num_format)


In [249]: print df_int.to_html(formatters=formatters)
<table border="1" class="dataframe">
  <thead>
    <tr style="text-align: right;">
      <th></th>
      <th>A</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th>0</th>
      <td>20,000</td>
    </tr>
    <tr>
      <th>1</th>
      <td>10,000</td>
    </tr>
  </tbody>
</table>

【讨论】:

【参考方案3】:

您始终可以将表格转换为 float64,然后根据需要使用 float_format,尤其是在您构建一个小表格以供查看时。这提供了一个快速解决方案,而不是分别处理整数和浮点数。

df.astype('float64',errors='ignore').to_html(float_format=lambda x: format(x,',.2f'))

errors='ignore' 用于防止在列无法转换为浮点数(如字符串)时引发异常。

【讨论】:

以上是关于格式化熊猫数据框中整数的千位分隔符的主要内容,如果未能解决你的问题,请参考以下文章

整个项目中所有数字的千位角分隔符

在python中使用本地化的千位分隔符和小数精度格式化数字

C++中的千位分隔符

如何显示或隐藏数字中的千位分隔符

用户键入时,columnGridView 中的千位分隔符和逗号

如何让php的localeconv返回正确的千位分隔符