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?

Phéon
la source
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
Andy Hayden
la source
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.

shen ke
la source
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)
ghollah kioko
la source