Jak wyświetlić pandy DataFrame elementów zmiennoprzecinkowych przy użyciu ciągu formatu dla kolumn?

166

Chciałbym wyświetlić ramkę danych pandy z podanym formatem przy użyciu print()i IPythona display(). Na przykład:

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

Chciałbym jakoś zmusić to do drukowania

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

bez konieczności modyfikowania samych danych lub tworzenia kopii, wystarczy zmienić sposób ich wyświetlania.

W jaki sposób mogę to zrobić?

Jason S.
źródło
2
Czy jest costto jedyna kolumna zmiennoprzecinkowa, czy są inne kolumny zmiennoprzecinkowe, których nie należy formatować $?
unutbu
Chciałbym to zrobić tylko dla kolumny kosztów (moje prawdziwe dane mają inne kolumny)
Jason S
zdaję sobie sprawę, że po dołączeniu znaku $ typ danych automatycznie zmienia się na obiekt.
Nguai al

Odpowiedzi:

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)

plony

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

ale działa to tylko wtedy, gdy chcesz, aby każda liczba zmiennoprzecinkowa była sformatowana za pomocą znaku dolara.

W przeciwnym razie, jeśli chcesz formatować dolara tylko dla niektórych liczb zmiennoprzecinkowych, myślę, że będziesz musiał wstępnie zmodyfikować ramkę danych (przekonwertować te zmiennoprzecinkowe na ciągi):

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)

plony

         cost       foo
foo   $123.46  123.4567
bar   $234.57  234.5678
baz   $345.68  345.6789
quux  $456.79  456.7890
unutbu
źródło
3
To rozwiązanie nadal działa poprawnie dla mnie od pandy 0.22.
Taylor Edmiston,
19
jak pokazano np. tutaj , możesz modyfikować opcje tylko dla danego bloku używającwith pd.option_context('display.float_format', '${:,.2f}'.format'):
Andre Holzner
1
Extra 'przed nawiasem zamykającym w komentarzu @AndreHolzner; w przeciwnym razie działa jak urok!
dTanMan
67

Jeśli nie chcesz modyfikować ramki danych, możesz użyć niestandardowego programu formatującego dla tej kolumny.

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

plony

        cost
foo  $123.46
bar  $234.57
baz  $345.68
quux $456.79
Chris Moore
źródło
2
Czy jest możliwe, aby program formatujący działał na wielopoziomowej kolumnie?
user2579685
3
ODPOWIEDŹ, ten przykład działa bez drugiej liniipd.options.display.float_format = '${:,.2f}'.format
pianoJames
56

Od wersji Pandas 0.17 istnieje teraz system stylizacji, który zasadniczo zapewnia sformatowane widoki ramki DataFrame przy użyciu ciągów formatu 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

który wyświetla

wprowadź opis obrazu tutaj

To jest obiekt widoku; sama ramka DataFrame nie zmienia formatowania, ale aktualizacje w ramce danych są odzwierciedlane w widoku:

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

wprowadź opis obrazu tutaj

Jednak wydaje się, że ma pewne ograniczenia:

  • Wydaje się, że dodanie nowych wierszy i / lub kolumn lokalnie powoduje niespójność w stylizowanym widoku (nie powoduje dodania etykiet wierszy / kolumn):

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

wprowadź opis obrazu tutaj

który wygląda dobrze, ale:

C

wprowadź opis obrazu tutaj

  • Formatowanie działa tylko dla wartości, a nie dla wpisów indeksu:

    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

wprowadź opis obrazu tutaj

Jason S.
źródło
2
Czy mogę używać DataFrame.style z wnętrza interpretera?
Jms,
23

Podobnie jak w przypadku unutbu powyżej, możesz również użyć applymapw następujący sposób:

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
źródło
Lubię używać tego podejścia przed wywołaniem, df.to_csv()aby upewnić się, że wszystkie kolumny w moim .csvpliku mają tę samą „szerokość cyfr”. Dzięki!
jeschwar
5

Lubię używać pandas.apply () z formatem Pythona ().

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

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

Ponadto można go łatwo używać z wieloma kolumnami ...

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
źródło
2

Możesz także ustawić ustawienia regionalne dla swojego regionu i ustawić float_format, aby używał formatu waluty. Spowoduje to automatyczne ustawienie znaku $ dla waluty w USA.

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
źródło
0

Podsumowanie:


    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
źródło