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

9 投票
3 回答
24806 浏览
提问于 2025-04-18 14:32

我想用 '{:,}'.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>

我哪里做错了呢?

3 个回答

1

你可以把你的表格转换成浮点数格式(float64),然后根据需要使用浮点数格式化,特别是当你只是想构建一个小表格来查看时。这样做可以避免分别处理整数和浮点数,提供了一个快速的解决方案。

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

errors='ignore'的意思是,当某一列无法转换为浮点数,比如字符串时,不会抛出错误。

14

在pandas(版本0.20.1及以上)中,想要轻松改变默认的整数格式并不容易。这个格式是写死在代码里的,具体在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>

撰写回答