我有一个pandas DataFrame,我希望有效地将多个列转换为分类列。我的第一个想法是使用pandas.DataFrame.apply
转换相关列。使用以下示例数据:
import pandas as pd
pdf = pd.DataFrame(dict(name= ('Earl', 'Eve', 'Alan', 'Randall', 'Danielle'),
age= ( 29, 17, 73, 31, 62),
gender= ( 'M', 'F', 'M', 'M', 'F'),
nationality=( 'US', 'UK', 'CAN', 'CAN', 'US'),
height= ( 182.9, 167.6, 175.3, 170.2, 172.8)),
columns=('name', 'age', 'gender', 'nationality', 'height'))
pdf = pdf.set_index('name')
>>> print(pdf)
age gender nationality height
name
Earl 29 M US 182.9
Eve 17 F UK 167.6
Alan 73 M CAN 175.3
Randall 31 M CAN 170.2
Danielle 62 F US 172.8
您可以看到apply
方法无效:
cat_list = {'gender', 'nationality'}
set_cat_list = lambda x: x.astype('category') if x.name in cat_list else x
dfa = pdf.apply(set_cat_list)
>>> print('Applied to subset: dtype={}'.format(dfa['gender'].dtype))
Applied to subset: dtype=object
这实际上不会引发错误,它只是在某个时刻以静默方式将列从分类转换回来。为了检查它是否实际正确射击,我添加了一个探测器:
in_cl = lambda x: x.name in cat_list
set_cat_list_alert = lambda x: (set_cat_list(x),
sys.stdout.write('{}: {}\n'.format(x.name, in_cl(x))))[0]
dfa = pdf.apply(set_cat_list_alert)
>>> print('Applied to subset: dtype={}'.format(dfa['gender'].dtype))
age: False
age: False
gender: True
nationality: True
height: False
Applied to subset: dtype=object
显然,所有内容都会正常启动,所以作为一个测试,看看这种方法是否可以正常工作,我尝试转换所有列,显然效果很好:
set_cat = lambda x: x.astype('category')
dfb = pdf.apply(set_cat)
>>> print('Applied to whole frame: dtype={}'.format(dfb['gender'].dtype))
Applied to whole frame: dtype=category
最后,我尝试使用for
循环来复制最终结果,以确保混合的分类/非分类列可以像这样共存:
dfc = pdf.copy()
for cat in cat_list:
dfc[cat] = pdf[cat].astype('category')
>>> print('For loop: dtype={}'.format(dfc['gender'].dtype))
For loop: dtype=category
所以我的问题是 - 为什么不能使用DataFrame.apply()
来设置其中一些列?我在这里缺少什么?
答案 0 :(得分:3)
这是一个错误,由此问题here表示,并在即将发布的0.17.0
版本中修复,该版本将于10月的第一周发布。
您可以通过以下方式安装0.17.0rc1
conda install pandas -c pandas