import pandas as pd
path1 = "/home/supertramp/Desktop/100&life_180_data.csv"
mydf = pd.read_csv(path1)
numcigar = {"Never":0 ,"1-5 Cigarettes/day" :1,"10-20 Cigarettes/day":4}
print mydf['Cigarettes']
mydf['CigarNum'] = mydf['Cigarettes'].apply(numcigar.get).astype(float)
print mydf['CigarNum']
mydf.to_csv('/home/supertramp/Desktop/powerRangers.csv')
Le fichier csv "100 & life_180_data.csv" contient des colonnes comme age, bmi, Cigarettes, Alocohol etc.
No int64
Age int64
BMI float64
Alcohol object
Cigarettes object
dtype: object
La colonne Cigarettes contient "Jamais" "1-5 cigarettes/jour", "10-20 cigarettes/jour". Je veux attribuer des poids à ces objets (Jamais, 1-5 cigarettes/jour, ....)
La sortie attendue est la nouvelle colonne CigarNum ajoutée qui ne comprend que les chiffres 0,1,2 CigarNum est comme prévu jusqu'à 8 lignes, puis affiche Nan jusqu'à la dernière ligne dans la colonne CigarNum
0 Never
1 Never
2 1-5 Cigarettes/day
3 Never
4 Never
5 Never
6 Never
7 Never
8 Never
9 Never
10 Never
11 Never
12 10-20 Cigarettes/day
13 1-5 Cigarettes/day
14 Never
...
167 Never
168 Never
169 10-20 Cigarettes/day
170 Never
171 Never
172 Never
173 Never
174 Never
175 Never
176 Never
177 Never
178 Never
179 Never
180 Never
181 Never
Name: Cigarettes, Length: 182, dtype: object
La sortie que j'obtiens ne devrait pas donner NaN après quelques premières lignes.
0 0
1 0
2 1
3 0
4 0
5 0
6 0
7 0
8 0
9 0
10 NaN
11 NaN
12 NaN
13 NaN
14 0
...
167 NaN
168 NaN
169 NaN
170 NaN
171 NaN
172 NaN
173 NaN
174 NaN
175 NaN
176 NaN
177 NaN
178 NaN
179 NaN
180 NaN
181 NaN
Name: CigarNum, Length: 182, dtype: float64
OK, le premier problème est que vous avez des espaces incorporés provoquant une application incorrecte de la fonction:
résoudre ce problème en utilisant str
vectorisé:
mydf['Cigarettes'] = mydf['Cigarettes'].str.replace(' ', '')
maintenant, créez votre nouvelle colonne devrait juste fonctionner:
mydf['CigarNum'] = mydf['Cigarettes'].apply(numcigar.get).astype(float)
[~ # ~] mise à jour [~ # ~]
Merci à @Jeff comme toujours d'avoir indiqué des façons de faire supérieures:
Vous pouvez donc appeler replace
au lieu d'appeler apply
:
mydf['CigarNum'] = mydf['Cigarettes'].replace(numcigar)
# now convert the types
mydf['CigarNum'] = mydf['CigarNum'].convert_objects(convert_numeric=True)
vous pouvez également utiliser la méthode factorize
également.
En y réfléchissant, pourquoi ne pas simplement définir les valeurs dict pour qu'elles soient flottantes de toute façon et ensuite vous évitez la conversion de type?
Alors:
numcigar = {"Never":0.0 ,"1-5 Cigarettes/day" :1.0,"10-20 Cigarettes/day":4.0}
Version 0.17.0 ou plus récente
convert_objects
est déconseillé depuis 0.17.0
, il a été remplacé par to_numeric
mydf['CigarNum'] = pd.to_numeric(mydf['CigarNum'], errors='coerce')
Ici errors='coerce'
renverra NaN
où les valeurs ne peuvent pas être converties en une valeur numérique, sans cela, il déclenchera une exception
Essayez d'utiliser cette fonction pour tous les problèmes de ce type:
def get_series_ids(x):
'''Function returns a pandas series consisting of ids,
corresponding to objects in input pandas series x
Example:
get_series_ids(pd.Series(['a','a','b','b','c']))
returns Series([0,0,1,1,2], dtype=int)'''
values = np.unique(x)
values2nums = dict(Zip(values,range(len(values))))
return x.replace(values2nums)