Formato de miles de separadores para enteros en un dataframe de pandas

Estoy tratando de usar '{:,}'.format(number) como el siguiente ejemplo para formatear un número en un dataframe de pandas:

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

El problema es que con un dataframe que tiene enteros no funciona, y en un dataframe con flotador funciona bien. Vea los ejemplos:

 # 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 #  # 0 #  20000 # </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 #  # 0 # 20,000.0 #  

¿Qué estoy haciendo mal?

El parámetro formatters en to_html tomará un diccionario de nombres de columna asignados a una función de formato. A continuación se muestra un ejemplo de una función para crear un dict que asigna la misma función tanto a flotantes como a ints.

 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) 
A
0 20,000
1 10,000

pandas (a partir de 0.20.1) no permite anular el formato de entero predeterminado de una manera fácil. Está codificado en duro en pandas.io.formats.format.IntArrayFormatter (la función labmda ):

 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 

Supongo que lo que realmente está preguntando es cómo puede anular el formato para todos los enteros : reemplace (“parche de mono”) el IntArrayFormatter para imprimir valores enteros con miles separados por comas de la siguiente manera:

 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 

Nota:

  • antes de 0.20.0, los formateadores estaban en pandas.formats.format .
  • antes de 0.18.1, los formateadores estaban en pandas.core.format .

Aparte

Para los flotadores, no es necesario saltar a través de esos aros, ya que hay una opción de configuración para ellos:

display.float_format : el invocable debe aceptar un número de punto flotante y devolver una cadena con el formato deseado del número. Esto se utiliza en algunos lugares como SeriesFormatter . Ver core.format.EngFormatter para un ejemplo.