Comment afficher les pandas DataFrame de flotteurs en utilisant une chaîne de format pour les colonnes?


166

Je voudrais afficher un dataframe pandas avec un format donné en utilisant print()et IPython display(). Par exemple:

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

Je voudrais en quelque sorte contraindre cela à l'impression

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

sans avoir à modifier les données elles-mêmes ou à créer une copie, changez simplement la façon dont elles sont affichées.

Comment puis-je faire ceci?


2
Est-ce costla seule colonne flottante ou y a-t-il d'autres colonnes flottantes qui ne doivent pas être formatées $?
unutbu

Je voudrais le faire pour la colonne de coût uniquement (mes données réelles ont d'autres colonnes)
Jason S

Je me rends compte qu'une fois que $ est attaché, le type de données change automatiquement en objet.
Nguai al

Réponses:


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)

rendements

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

mais cela ne fonctionne que si vous voulez que chaque flottant soit formaté avec un signe dollar.

Sinon, si vous voulez un formatage en dollars pour certains flottants uniquement, je pense que vous devrez pré-modifier le dataframe (convertir ces flottants en chaînes):

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)

rendements

         cost       foo
foo   $123.46  123.4567
bar   $234.57  234.5678
baz   $345.68  345.6789
quux  $456.79  456.7890

3
Cette solution fonctionne toujours correctement pour moi à partir de pandas 0.22.
Taylor Edmiston

19
comme indiqué par exemple ici , vous pouvez modifier les options uniquement pour un bloc donné en utilisantwith pd.option_context('display.float_format', '${:,.2f}'.format'):
Andre Holzner

1
Extra 'avant la parenthèse fermante sur le commentaire de @AndreHolzner; sinon, ça marche comme un charme!
dTanMan

67

Si vous ne souhaitez pas modifier le dataframe, vous pouvez utiliser un formateur personnalisé pour cette colonne.

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})

rendements

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

2
Est-il possible de faire travailler le formateur sur une colonne à plusieurs niveaux?
user2579685

3
AFAICT, cet exemple fonctionne sans la deuxième lignepd.options.display.float_format = '${:,.2f}'.format
pianoJames

56

Depuis Pandas 0.17, il existe maintenant un système de style qui fournit essentiellement des vues formatées d'un DataFrame à l'aide de chaînes au format 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

qui affiche

entrez la description de l'image ici

Ceci est un objet de vue; le DataFrame lui-même ne change pas la mise en forme, mais les mises à jour du DataFrame sont reflétées dans la vue:

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

entrez la description de l'image ici

Cependant, il semble avoir certaines limites:

  • L'ajout de nouvelles lignes et / ou colonnes en place semble entraîner une incohérence dans la vue stylisée (n'ajoute pas d'étiquettes de ligne / colonne):

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

entrez la description de l'image ici

ce qui semble correct mais:

C

entrez la description de l'image ici

  • Le formatage fonctionne uniquement pour les valeurs, pas pour les entrées d'index:

    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

entrez la description de l'image ici


2
Puis-je utiliser le DataFrame.style depuis l'interpréteur?
Jms

23

Semblable à unutbu ci-dessus, vous pouvez également utiliser applymapcomme suit:

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)

J'aime utiliser cette approche avant d'appeler df.to_csv()pour m'assurer que toutes les colonnes de mon .csvfichier ont la même «largeur de chiffre». Merci!
jeschwar

5

J'aime utiliser pandas.apply () avec le format 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)

En outre, il peut être facilement utilisé avec plusieurs colonnes ...

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)

2

Vous pouvez également définir les paramètres régionaux de votre région et définir float_format pour utiliser un format de devise. Cela définira automatiquement le signe $ pour la devise aux États-Unis.

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

0

résumé:


    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
    """
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.