Преобразование строковых объектов в int/float с помощью pandas
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')
В файле csv "100 & life_180_data.csv" содержатся такие столбцы, как возраст, bmi, сигареты, Alocohol и т.д.
No int64
Age int64
BMI float64
Alcohol object
Cigarettes object
dtype: object
Сигаретная колонка содержит "Никогда" "1-5 Сигареты/день", "10-20 сигарет/день".
Я хочу присвоить весу этим объектам (Никогда, 1-5 Cigarettes/day,....)
Ожидаемый вывод - это новый столбец CigarNum, который содержит только числа 0,1,2
CigarNum как ожидается до 8 строк, а затем показывает Nan до последнего ряда в столбце 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
Результат, который я получаю, не дает NaN после нескольких первых строк.
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
Ответы
Ответ 1
ОК, первая проблема заключается в том, что у вас есть встроенные пространства, из-за которых функция неправильно применяется:
исправить это с помощью векторизованного str
:
mydf['Cigarettes'] = mydf['Cigarettes'].str.replace(' ', '')
теперь создайте новый столбец, который должен работать:
mydf['CigarNum'] = mydf['Cigarettes'].apply(numcigar.get).astype(float)
UPDATE
Благодаря @Jeff, как всегда, указывая на превосходные способы делать вещи:
Итак, вы можете вызвать replace
вместо вызова apply
:
mydf['CigarNum'] = mydf['Cigarettes'].replace(numcigar)
# now convert the types
mydf['CigarNum'] = mydf['CigarNum'].convert_objects(convert_numeric=True)
вы также можете использовать метод factorize
.
Размышление об этом, почему бы не просто установить значения dict в качестве плавающих в любом случае, а затем избежать преобразования типов?
Итак:
numcigar = {"Never":0.0 ,"1-5 Cigarettes/day" :1.0,"10-20 Cigarettes/day":4.0}
Версия 0.17.0 или новее
convert_objects
устарел с 0.17.0
, это было заменено на to_numeric
mydf['CigarNum'] = pd.to_numeric(mydf['CigarNum'], errors='coerce')
Здесь errors='coerce'
будет возвращать NaN
, где значения не могут быть преобразованы в числовое значение, без этого оно приведет к возникновению исключения
Ответ 2
Попробуйте использовать эту функцию для всех задач такого рода:
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)