Convertir les chaînes numériques avec des virgules dans pandas DataFrame en float


88

J'ai un DataFrame qui contient des nombres sous forme de chaînes avec des virgules pour le marqueur des milliers. J'ai besoin de les convertir en flotteurs.

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

Je suppose que j'ai besoin d'utiliser locale.atof. En effet

df[0].apply(locale.atof)

fonctionne comme prévu. Je reçois une série de flotteurs.

Mais lorsque je l'applique au DataFrame, j'obtiens une erreur.

df.apply(locale.atof)

TypeError: ("impossible de convertir la série en", u'arrivée à l'index 0 ')

et

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

donne une autre erreur:

ValueError: ('littéral invalide pour float (): 1,200', u 's'est produit à l'index 0')

Alors, comment puis-je convertir ces DataFramechaînes en un DataFrame de flottants?


2
Ancienne question, mais l'OP obtient cette erreur car applysur un DataFrame passe une colonne entière à la fonction sous forme de série (dans ce cas locale.atof, qui attend une chaîne). Si vous utilisez la applymapméthode utilisée par @AndyHayden dans la réponse ci-dessous, vous devriez pouvoir le faire très bien.
TC Proctor

Réponses:


144

Si vous lisez à partir de csv, vous pouvez utiliser l' argument des milliers :

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

Cette méthode est susceptible d'être plus efficace que d'effectuer l'opération en tant qu'étape distincte.


Vous devez d'abord définir les paramètres régionaux :

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

J'aurais dû dire que j'ai défini les paramètres régionaux. J'obtiens toujours l'erreur.
pheon

2
Mais j'utilise df.read_fwf, et cela a aussi l'option "milliers = ','", qui fonctionne. Merci.
pheon

Là encore, pourquoi df.applymap (atof) fonctionne-t-il pour vous mais pas pour moi? Ma langue est «en_US.UTF-8».
pheon

10
J'ai voté pour la pointe d'argument «milliers» pour la fonction read_csv. Cela a très bien fonctionné pour moi.
rockfakie

3
Je voulais ajouter que vous pouvez également utiliser "decimal = ','" si vous avez affaire à des flottants.
VessoVit

32

Vous pouvez utiliser la méthode pandas.Series.str.replace :

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

Cette méthode peut supprimer ou remplacer la virgule dans la chaîne.


1
Je reçois "AttributeError: l'objet 'DataFrame' n'a pas d'attribut 'str'", je ne sais pas pourquoi ...
krassowski

1
Mais cela fonctionne:df.apply(lambda x: x.str.replace(',', '').astype(float), axis=1)
krassowski

21

Vous pouvez convertir une colonne à la fois comme ceci:

df['colname'] = df['colname'].str.replace(',', '').astype(float)
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.