¿Cómo mostrar pandas DataFrame de flotadores usando una cadena de formato para columnas?

166

Me gustaría mostrar un marco de datos de pandas con un formato determinado usando print()y el IPython display(). Por ejemplo:

df = pd.DataFrame([123.4567, 234.5678, 345.6789, 456.7890],
                  index=['foo','bar','baz','quux'],
                  columns=['cost'])
print df

         cost
foo   123.4567
bar   234.5678
baz   345.6789
quux  456.7890

Me gustaría de alguna manera obligar a esto a imprimir

         cost
foo   $123.46
bar   $234.57
baz   $345.68
quux  $456.79

sin tener que modificar los datos en sí o crear una copia, simplemente cambie la forma en que se muestran.

¿Cómo puedo hacer esto?

Jason S
fuente
2
¿Es costla única columna flotante, o hay otras columnas flotantes que no deberían formatearse $?
unutbu
Me gustaría hacerlo solo para la columna de costos (mis datos reales tienen otras columnas)
Jason S
Me doy cuenta de que una vez que se adjunta $, el tipo de datos cambia automáticamente a objeto.
Nguai al

Respuestas:

284
import pandas as pd
pd.options.display.float_format = '${:,.2f}'.format
df = pd.DataFrame([123.4567, 234.5678, 345.6789, 456.7890],
                  index=['foo','bar','baz','quux'],
                  columns=['cost'])
print(df)

rendimientos

        cost
foo  $123.46
bar  $234.57
baz  $345.68
quux $456.79

pero esto solo funciona si desea que cada flotador se formatee con un signo de dólar.

De lo contrario, si desea formatear en dólares solo para algunos flotantes, creo que tendrá que modificar previamente el marco de datos (convirtiendo esos flotantes en cadenas):

import pandas as pd
df = pd.DataFrame([123.4567, 234.5678, 345.6789, 456.7890],
                  index=['foo','bar','baz','quux'],
                  columns=['cost'])
df['foo'] = df['cost']
df['cost'] = df['cost'].map('${:,.2f}'.format)
print(df)

rendimientos

         cost       foo
foo   $123.46  123.4567
bar   $234.57  234.5678
baz   $345.68  345.6789
quux  $456.79  456.7890
unutbu
fuente
3
Esta solución todavía funciona correctamente para mí a partir de pandas 0.22.
Taylor Edmiston
19
como se muestra, por ejemplo , aquí , puede modificar las opciones solo para un bloque dado usandowith pd.option_context('display.float_format', '${:,.2f}'.format'):
Andre Holzner
1
Extra 'antes del paréntesis de cierre en el comentario de @AndreHolzner; de lo contrario, funciona como un encanto!
dTanMan
67

Si no desea modificar el marco de datos, puede usar un formateador personalizado para esa columna.

import pandas as pd
pd.options.display.float_format = '${:,.2f}'.format
df = pd.DataFrame([123.4567, 234.5678, 345.6789, 456.7890],
                  index=['foo','bar','baz','quux'],
                  columns=['cost'])


print df.to_string(formatters={'cost':'${:,.2f}'.format})

rendimientos

        cost
foo  $123.46
bar  $234.57
baz  $345.68
quux $456.79
Chris Moore
fuente
2
¿Es posible hacer que el formateador funcione en una columna multinivel?
user2579685
3
AFAICT, este ejemplo funciona sin la segunda líneapd.options.display.float_format = '${:,.2f}'.format
pianoJames
56

A partir de Pandas 0.17 ahora hay un sistema de diseño que esencialmente proporciona vistas formateadas de un DataFrame utilizando cadenas de formato Python :

import pandas as pd
import numpy as np

constants = pd.DataFrame([('pi',np.pi),('e',np.e)],
                   columns=['name','value'])
C = constants.style.format({'name': '~~ {} ~~', 'value':'--> {:15.10f} <--'})
C

que muestra

ingrese la descripción de la imagen aquí

Este es un objeto de vista; el DataFrame en sí no cambia el formato, pero las actualizaciones en el DataFrame se reflejan en la vista:

constants.name = ['pie','eek']
C

ingrese la descripción de la imagen aquí

Sin embargo, parece tener algunas limitaciones:

  • Agregar nuevas filas y / o columnas en el lugar parece causar inconsistencia en la vista con estilo (no agrega etiquetas de fila / columna):

    constants.loc[2] = dict(name='bogus', value=123.456)
    constants['comment'] = ['fee','fie','fo']
    constants
    

ingrese la descripción de la imagen aquí

que se ve bien pero:

C

ingrese la descripción de la imagen aquí

  • El formateo solo funciona para valores, no para entradas de índice:

    constants = pd.DataFrame([('pi',np.pi),('e',np.e)],
                   columns=['name','value'])
    constants.set_index('name',inplace=True)
    C = constants.style.format({'name': '~~ {} ~~', 'value':'--> {:15.10f} <--'})
    C
    

ingrese la descripción de la imagen aquí

Jason S
fuente
2
¿Puedo usar el DataFrame.style desde el intérprete?
Jms
23

Similar a unutbu anterior, también puede usar applymaplo siguiente:

import pandas as pd
df = pd.DataFrame([123.4567, 234.5678, 345.6789, 456.7890],
                  index=['foo','bar','baz','quux'],
                  columns=['cost'])

df = df.applymap("${0:.2f}".format)
sedeh
fuente
Me gusta usar este enfoque antes de llamar df.to_csv()para asegurarme de que todas las columnas de mi .csvarchivo tengan el mismo "ancho de dígitos". ¡Gracias!
jeschwar
5

Me gusta usar pandas.apply () con formato python ().

import pandas as pd
s = pd.Series([1.357, 1.489, 2.333333])

make_float = lambda x: "${:,.2f}".format(x)
s.apply(make_float)

Además, se puede usar fácilmente con múltiples columnas ...

df = pd.concat([s, s * 2], axis=1)

make_floats = lambda row: "${:,.2f}, ${:,.3f}".format(row[0], row[1])
df.apply(make_floats, axis=1)
Selah
fuente
2

También puede establecer la configuración regional en su región y establecer float_format para usar un formato de moneda. Esto establecerá automáticamente el signo $ para la moneda en EE. UU.

import locale

locale.setlocale(locale.LC_ALL, "en_US.UTF-8")

pd.set_option("float_format", locale.currency)

df = pd.DataFrame(
    [123.4567, 234.5678, 345.6789, 456.7890],
    index=["foo", "bar", "baz", "quux"],
    columns=["cost"],
)
print(df)

        cost
foo  $123.46
bar  $234.57
baz  $345.68
quux $456.79
Vlad Bezden
fuente
0

resumen:


    df = pd.DataFrame({'money': [100.456, 200.789], 'share': ['100,000', '200,000']})
    print(df)
    print(df.to_string(formatters={'money': '${:,.2f}'.format}))
    for col_name in ('share',):
        df[col_name] = df[col_name].map(lambda p: int(p.replace(',', '')))
    print(df)
    """
        money    share
    0  100.456  100,000
    1  200.789  200,000

        money    share
    0 $100.46  100,000
    1 $200.79  200,000

         money   share
    0  100.456  100000
    1  200.789  200000
    """
Carson
fuente