Como exibir o DataFrame de pandas de carros alegóricos usando uma string de formato para colunas?

164

Gostaria de exibir um dataframe de pandas com um determinado formato usando print()e o IPython display(). Por exemplo:

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

Eu gostaria de de alguma forma coagir isso a imprimir

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

sem precisar modificar os dados em si ou criar uma cópia, basta alterar a maneira como eles são exibidos.

Como posso fazer isso?

Jason S
fonte
2
É costa única coluna flutuante ou existem outras colunas flutuantes que não devem ser formatadas $?
unutbu
Eu gostaria de fazê-lo apenas para a coluna de custo (meus dados reais têm outras colunas)
Jason S
Eu percebo que uma vez que $ é anexado, o tipo de dados muda automaticamente para o objeto.
Nguai al

Respostas:

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)

rendimentos

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

mas isso só funciona se você quiser que cada flutuador seja formatado com um cifrão.

Caso contrário, se você quiser formatação em dólar apenas para alguns carros alegóricos, acho que precisará pré-modificar o quadro de dados (convertendo esses carros alegóricos em seqüências de caracteres):

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)

rendimentos

         cost       foo
foo   $123.46  123.4567
bar   $234.57  234.5678
baz   $345.68  345.6789
quux  $456.79  456.7890
unutbu
fonte
3
Essa solução ainda funciona corretamente para mim a partir dos pandas 0,22.
Taylor Edmiston
19
como mostrado, por exemplo, aqui , você pode modificar as opções somente para o um determinado bloco usandowith pd.option_context('display.float_format', '${:,.2f}'.format'):
Andre Holzner
1
Extra 'antes do parêntese de fechamento no comentário de @AndreHolzner; caso contrário, funciona como um encanto!
dTanMan 16/03
67

Se você não quiser modificar o quadro de dados, poderá usar um formatador personalizado para essa coluna.

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

rendimentos

        cost
foo  $123.46
bar  $234.57
baz  $345.68
quux $456.79
Chris Moore
fonte
2
É possível fazer o formatador funcionar em uma coluna multinível?
User2579685
3
AFAICT, este exemplo funciona sem a segunda linhapd.options.display.float_format = '${:,.2f}'.format
pianoJames
55

A partir do Pandas 0.17, agora existe um sistema de estilo que fornece essencialmente visualizações formatadas de um DataFrame usando cadeias de caracteres 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 exibe

insira a descrição da imagem aqui

Este é um objeto de exibição; o próprio DataFrame não altera a formatação, mas as atualizações no DataFrame são refletidas na exibição:

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

insira a descrição da imagem aqui

No entanto, parece ter algumas limitações:

  • Adicionar novas linhas e / ou colunas no local parece causar inconsistência na exibição estilizada (não adiciona rótulos de linha / coluna):

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

insira a descrição da imagem aqui

que parece ok, mas:

C

insira a descrição da imagem aqui

  • A formatação funciona apenas para valores, não 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

insira a descrição da imagem aqui

Jason S
fonte
2
Posso usar o DataFrame.style de dentro do intérprete?
Jms
23

Semelhante ao unutbu acima, você também pode usar applymapo seguinte:

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
fonte
Eu gosto de usar essa abordagem antes de ligar df.to_csv()para garantir que todas as colunas do meu .csvarquivo tenham a mesma "largura de dígito". Obrigado!
jeschwar
5

Eu gosto de usar pandas.apply () com 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)

Além disso, pode ser facilmente usado com várias colunas ...

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
fonte
2

Você também pode definir o código de idioma para sua região e definir float_format para usar um formato de moeda. Isso definirá automaticamente o sinal de $ para a moeda nos EUA.

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
fonte
0

resumo:


    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
fonte