Python 熊猫-为什么能';t DataFrame.apply可用于将某些列设置为分类列

Python 熊猫-为什么能';t DataFrame.apply可用于将某些列设置为分类列,python,pandas,Python,Pandas,我有一个熊猫数据框架,我想有效地将多个列转换为分类列。我的第一个想法是使用pandas.DataFrame.apply转换相关列。使用以下示例数据: import pandas as pd pdf = pd.DataFrame(dict(name= ('Earl', 'Eve', 'Alan', 'Randall', 'Danielle'), age= ( 29, 17, 73, 31,

我有一个熊猫数据框架,我想有效地将多个列转换为分类列。我的第一个想法是使用
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
这实际上并不会引发错误,它只是在某个时刻将列从categorical悄悄地转换回来。为了检查它是否正确发射,我添加了一个探测器:

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()
将其中一些列设置为分类列?我在这里遗漏了什么?

这是一个bug,由本期指出,并在10月第一周即将发布的
0.17.0
版本中修复

您可以通过以下方式安装
0.17.0rc1


conda安装pandas-c pandas

什么版本?您的应用代码在
0.16.2
中为我工作,使用
0.16.2
/Python 3.4.3和
0.15.2
/Python 2.7.9进行了测试。我怀疑这是一个bug,值得在github上提交一个问题:。@AndyHayden是的,很好。如果它被证明是一个bug而不是一个特性,我打算这样做。这在10月的第一周发布的0.17.0中得到了修复。如果愿意,您可以
conda安装pandas-c pandas
立即获取(rc1)