Appliquer pandas.to_numeric
à une colonne de trame de données qui contient des chaînes qui représentent des nombres (et éventuellement d'autres chaînes non analysables) entraîne un message d'erreur comme celui-ci:
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-66-07383316d7b6> in <module>()
1 for column in shouldBeNumericColumns:
----> 2 trainData[column] = pandas.to_numeric(trainData[column])
/usr/local/lib/python3.5/site-packages/pandas/tools/util.py in to_numeric(arg, errors)
113 try:
114 values = lib.maybe_convert_numeric(values, set(),
--> 115 coerce_numeric=coerce_numeric)
116 except:
117 if errors == 'raise':
pandas/src/inference.pyx in pandas.lib.maybe_convert_numeric (pandas/lib.c:53558)()
pandas/src/inference.pyx in pandas.lib.maybe_convert_numeric (pandas/lib.c:53344)()
ValueError: Unable to parse string
Ne serait-il pas utile de voir quelle valeur n'a pas pu être analysée?
Je pense que vous pouvez ajouter le paramètre errors='coerce'
pour convertir les mauvaises valeurs non numériques en NaN
, puis vérifiez ces valeurs par isnull
et utilisez boolean indexing
:
print (df[pd.to_numeric(df.col, errors='coerce').isnull()])
Échantillon:
df = pd.DataFrame({'B':['a','7','8'],
'C':[7,8,9]})
print (df)
B C
0 a 7
1 7 8
2 8 9
print (df[pd.to_numeric(df.B, errors='coerce').isnull()])
B C
0 a 7
Ou si besoin, trouvez toutes les chaînes dans une colonne mixte - nombre avec des valeurs de chaîne vérifiez type
des valeurs si est string
:
df = pd.DataFrame({'B':['a',7, 8],
'C':[7,8,9]})
print (df)
B C
0 a 7
1 7 8
2 8 9
print (df[df.B.apply(lambda x: isinstance(x, str))])
B C
0 a 7
J'ai pensé la même chose, et je ne sais pas s'il y a une meilleure façon, mais ma solution de contournement actuelle consiste à rechercher des caractères qui ne sont pas des nombres ou des points. Cela pose généralement le problème. Il y a des cas où plusieurs périodes peuvent causer un problème, mais je les ai trouvées rares.
import pandas as pd
import re
non_numeric = re.compile(r'[^\d.]+')
df = pd.DataFrame({'a': [3,2,'NA']})
df.loc[df['a'].str.contains(non_numeric)]