Converta strings de números com vírgulas no DataFrame do pandas para flutuar

88

Eu tenho um DataFrame que contém números como strings com vírgulas para o marcador de milhares. Eu preciso convertê-los em carros alegóricos.

a = [['1,200', '4,200'], ['7,000', '-0.03'], [ '5', '0']]
df=pandas.DataFrame(a)

Acho que preciso usar locale.atof. De fato

df[0].apply(locale.atof)

funciona como esperado. Recebo uma série de carros alegóricos.

Mas quando eu o aplico ao DataFrame, recebo um erro.

df.apply(locale.atof)

TypeError: ("não é possível converter a série em", ocorreu no índice 0 ')

e

df[0:1].apply(locale.atof)

dá outro erro:

ValueError: ('literal inválido para float (): 1.200', u'ocorrido no índice 0 ')

Então, como faço para converter isso DataFramede strings em um DataFrame de floats?

feão
fonte
2
Pergunta antiga, mas o OP está recebendo aquele erro porque applyem um DataFrame passa uma coluna inteira para a função como uma série (neste caso locale.atof, que espera uma string). Se você usar o applymapmétodo que @AndyHayden usa na resposta a seguir, deve conseguir fazer isso perfeitamente.
TC Proctor

Respostas:

144

Se você está lendo a partir do csv , pode usar o argumento de milhares :

df.read_csv('foo.tsv', sep='\t', thousands=',')

Esse método provavelmente é mais eficiente do que executar a operação como uma etapa separada.


Você precisa definir a localidade primeiro:

In [ 9]: import locale

In [10]: from locale import atof

In [11]: locale.setlocale(locale.LC_NUMERIC, '')
Out[11]: 'en_GB.UTF-8'

In [12]: df.applymap(atof)
Out[12]:
      0        1
0  1200  4200.00
1  7000    -0.03
2     5     0.00
Andy Hayden
fonte
Eu deveria ter dito que defini o local. Eu ainda tenho o erro.
feão
2
Mas estou usando df.read_fwf, e ele também tem a opção "milhares = ','", que funciona. Obrigado.
Feon
Então, novamente, por que df.applymap (atof) funciona para você, mas não para mim? Minha localidade é 'en_US.UTF-8'.
Feon
10
Votei na dica do argumento 'milhares' para a função read_csv. Isso funcionou muito bem para mim.
rockfakie
3
Eu gostaria de acrescentar que você também pode usar "decimal = ','" se estiver lidando com flutuadores.
VessoVit
32

Você pode usar o método pandas.Series.str.replace :

df.iloc[:,:].str.replace(',', '').astype(float)

Este método pode remover ou substituir a vírgula na string.

shen ke
fonte
1
Estou recebendo "AttributeError: 'DataFrame' objeto não tem atributo 'str'", não faço ideia por que ...
krassowski
1
Mas isso funciona:df.apply(lambda x: x.str.replace(',', '').astype(float), axis=1)
krassowski
21

Você pode converter uma coluna de cada vez desta forma:

df['colname'] = df['colname'].str.replace(',', '').astype(float)
ghollah kioko
fonte