在pandas数据帧中格式化整数千个分隔符

时间:2014-07-23 23:17:18

标签: python pandas

我尝试使用下面示例中的'{:,}'.format(number)格式化pandas数据帧中的数字:

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

问题是,对于具有整数的数据帧不起作用,并且在具有float的数据框中工作正常。参见示例:

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

我做错了什么?

3 个答案:

答案 0 :(得分:8)

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

我假设您实际要求的是如何覆盖所有整数的格式 :替换(“monkey patch”)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:callable应该接受一个浮点数并返回一个具有所需数字格式的字符串。这在某些地方使用,例如SeriesFormatter。有关示例,请参阅core.format.EngFormatter

答案 1 :(得分:6)

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

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>

答案 2 :(得分:1)

您始终可以将表强制转换为float64,然后根据需要使用float_format,尤其是在构造用于查看目的的小表时。与其分别处理int和float,这提供了一种快速的解决方案。

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

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