2017-05-23 2 views
2

Compte tenu du fichier:Pandas lecture NULL comme NaN flottant au lieu de str

$ cat test.csv 
a,b,c,NULL,d 
e,f,g,h,i 
j,k,l,m,n 

Lorsque la 3ème colonne est à traiter comme str.

Quand je l'ai fait une fonction de chaîne sur la colonne, pandas a lu la NULL str comme un flotteur NaN:

>>> import pandas as pd 
>>> df = pd.read_csv('test.csv', names=[0,1,2,3,4], dtype={0:str, 1:str, 2:str, 3:str, 4:str}) 

>>> df[3].apply(str.strip) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "/usr/local/lib/python3.5/site-packages/pandas/core/series.py", line 2355, in apply 
    mapped = lib.map_infer(values, f, convert=convert_dtype) 
    File "pandas/_libs/src/inference.pyx", line 1569, in pandas._libs.lib.map_infer (pandas/_libs/lib.c:66440) 
TypeError: descriptor 'strip' requires a 'str' object but received a 'float' 

Pour vérifier:

>>> for i in df[3]: 
... print (type(i), i) 
... 
<class 'float'> nan 
<class 'str'> h 
<class 'str'> m 

J'ai spécifié le dtype lors de l'initialisation mais d'une manière ou d'une autre il a été dépassé.

Comment forcer le type d'une colonne spécifique à être réparé?

Est-il possible de trouver automatiquement ces NaN flotteurs anormaux et puis revenir à 'NULL' chaîne?

+0

BTW, est-ce un bug 'pandas'? Ou une caractéristique? – alvas

+0

Une caractéristique, c'est: P – alvas

Répondre

4

Pour moi fonctionne astype:

df[3] = df[3].astype(str) 

for i in df[3]: 
    print (type(i), i) 

<class 'str'> nan 
<class 'str'> h 
<class 'str'> m 

Une autre solution est d'utiliser keep_default_na=False dans read_csv:

import pandas as pd 
from pandas.compat import StringIO 

temp=u"""a,b,c,NULL,d 
e,f,g,h,i 
j,k,l,m,n""" 
#after testing replace 'StringIO(temp)' to 'filename.csv' 
df = pd.read_csv(StringIO(temp), names=[0,1,2,3,4], keep_default_na=False) 
print (df) 
    0 1 2  3 4 
0 a b c NULL d 
1 e f g  h i 
2 j k l  m n 

for i in df[3]: 
    print (type(i), i) 
<class 'str'> NULL 
<class 'str'> h 
<class 'str'> m 

Ensuite est l'utilisation possible na_values paramètre si besoin analyser NaN dans les colonnes numériques, mais il doit être différent par exemple NA:

import pandas as pd 
from pandas.compat import StringIO 

temp=u"""a,b,c,NULL,1 
e,f,g,h,2 
j,k,l,m,NA""" 
#after testing replace 'StringIO(temp)' to 'filename.csv' 
df = pd.read_csv(StringIO(temp), names=[0,1,2,3,4], keep_default_na=False, na_values=['NA']) 
print (df) 
    0 1 2  3 4 
0 a b c NULL 1.0 
1 e f g  h 2.0 
2 j k l  m NaN 

for i in df[3]: 
    print (type(i), i) 
<class 'str'> NULL 
<class 'str'> h 
<class 'str'> m 

for i in df[4]: 
    print (type(i), i) 
<class 'numpy.float64'> 1.0 
<class 'numpy.float64'> 2.0 
<class 'numpy.float64'> nan 
+0

Cela doit être fait après l'initialisation droite? C'est un problème mineur mais il déforme le 'NULL' à' nan' = ( – alvas

+1

Merci @jezrael! Le 'keep_default_na' fonctionne bien =) – alvas

+0

Super, heureux peut aider! – jezrael