在pandas数据框中为整数格式化千位分隔符

9

我想要使用如下面例子的代码'{:,}'.format(number)在pandas数据帧中格式化数字:

# 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>

我做错了什么?

1
我不确定为什么它不能用于整数,但是你不能使用浮点数并指定精度,例如 {:,.0f} 吗? - dmvianna
1
你需要为int指定一个单独的格式化程序;请参考此问题的示例。 - behzad.nouri
1
但是在那个问题中,他使用了我使用的相同格式 int_frmt = lambda x: '{:,}'.format( x ) - Javier Cárdenas
3个回答

14

截至0.20.1版本,pandas不支持轻松覆盖默认的整数格式。在pandas.io.formats.format.IntArrayFormatter中已经硬编码了默认格式(使用lambda函数):

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中。

附言

对于浮点数,您无需跳过这些步骤,因为有一个配置选项可供使用:

display.float_format:该可调用函数应接受浮点数并返回具有所需数字格式的字符串。这在一些地方(如SeriesFormatter)中使用。请参见core.format.EngFormatter以获取示例。


8
to_html中的formatters参数将会接收一个列名字典和格式化函数的映射。以下是构建将相同函数映射到浮点数和整数的字典的示例函数。
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>

1
您可以始终将表格转换为float64,然后根据需要使用float_format,特别是如果您正在构建用于查看的小表格。这样做可以避免分别处理整数和浮点数,从而提供了一个快速的解决方案。
df.astype('float64',errors='ignore').to_html(float_format=lambda x: format(x,',.2f'))
'errors=\'ignore\'是为了防止在无法将列转换为浮点数(如字符串)时引发异常。'

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接