<p dir="auto">Per <a href="http://stackoverflow.com/q/32873402/467366" rel="nofollow">this SO question</a>, using <code class="notranslate">apply()</code> to convert multiple <code class="notranslate">DataFrame</code> columns to categorical does not work unless <em>all</em> columns are categorical.</p>
<p dir="auto">An MWE demonstrating the issue can be found at <a href="https://gist.github.com/pganssle/4d0b4c326f0f8e80ba50">this gist</a> for easy copy-paste.</p>
<p dir="auto">Using this for example data:</p>
<div class="highlight highlight-source-python notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="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')
&gt;&gt;&gt; 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"><pre class="notranslate"><span class="pl-k">import</span> <span class="pl-s1">pandas</span> <span class="pl-k">as</span> <span class="pl-s1">pd</span>

<span class="pl-s1">pdf</span> <span class="pl-c1">=</span> <span class="pl-s1">pd</span>.<span class="pl-v">DataFrame</span>(<span class="pl-en">dict</span>(<span class="pl-s1">name</span><span class="pl-c1">=</span>       (<span class="pl-s">'Earl'</span>, <span class="pl-s">'Eve'</span>, <span class="pl-s">'Alan'</span>, <span class="pl-s">'Randall'</span>, <span class="pl-s">'Danielle'</span>),
                        <span class="pl-s1">age</span><span class="pl-c1">=</span>        (    <span class="pl-c1">29</span>,    <span class="pl-c1">17</span>,     <span class="pl-c1">73</span>,        <span class="pl-c1">31</span>,         <span class="pl-c1">62</span>),
                        <span class="pl-s1">gender</span><span class="pl-c1">=</span>     (   <span class="pl-s">'M'</span>,   <span class="pl-s">'F'</span>,    <span class="pl-s">'M'</span>,       <span class="pl-s">'M'</span>,        <span class="pl-s">'F'</span>),
                        <span class="pl-s1">nationality</span><span class="pl-c1">=</span>(  <span class="pl-s">'US'</span>,  <span class="pl-s">'UK'</span>,  <span class="pl-s">'CAN'</span>,     <span class="pl-s">'CAN'</span>,       <span class="pl-s">'US'</span>),
                        <span class="pl-s1">height</span><span class="pl-c1">=</span>     ( <span class="pl-c1">182.9</span>, <span class="pl-c1">167.6</span>,  <span class="pl-c1">175.3</span>,     <span class="pl-c1">170.2</span>,      <span class="pl-c1">172.8</span>)),
                   <span class="pl-s1">columns</span><span class="pl-c1">=</span>(<span class="pl-s">'name'</span>, <span class="pl-s">'age'</span>, <span class="pl-s">'gender'</span>, <span class="pl-s">'nationality'</span>, <span class="pl-s">'height'</span>))
<span class="pl-s1">pdf</span> <span class="pl-c1">=</span> <span class="pl-s1">pdf</span>.<span class="pl-en">set_index</span>(<span class="pl-s">'name'</span>)
<span class="pl-c1">&gt;&gt;</span><span class="pl-c1">&gt;</span> <span class="pl-en">print</span>(<span class="pl-s1">pdf</span>)

          <span class="pl-s1">age</span> <span class="pl-s1">gender</span> <span class="pl-s1">nationality</span>  <span class="pl-s1">height</span>
<span class="pl-s1">name</span>
<span class="pl-v">Earl</span>       <span class="pl-c1">29</span>      <span class="pl-v">M</span>          <span class="pl-v">US</span>   <span class="pl-c1">182.9</span>
<span class="pl-v">Eve</span>        <span class="pl-c1">17</span>      <span class="pl-v">F</span>          <span class="pl-v">UK</span>   <span class="pl-c1">167.6</span>
<span class="pl-v">Alan</span>       <span class="pl-c1">73</span>      <span class="pl-v">M</span>         <span class="pl-v">CAN</span>   <span class="pl-c1">175.3</span>
<span class="pl-v">Randall</span>    <span class="pl-c1">31</span>      <span class="pl-v">M</span>         <span class="pl-v">CAN</span>   <span class="pl-c1">170.2</span>
<span class="pl-v">Danielle</span>   <span class="pl-c1">62</span>      <span class="pl-v">F</span>          <span class="pl-v">US</span>   <span class="pl-c1">172.8</span></pre></div>
<p dir="auto">I tried to use <code class="notranslate">pdf.apply()</code> to convert <code class="notranslate">'gender'</code> and <code class="notranslate">'nationality'</code> to categorical columns:</p>
<div class="highlight highlight-source-python notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="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)

&gt;&gt;&gt; print('Applied to subset: dtype={}'.format(dfa['gender'].dtype))
Applied to subset: dtype=object"><pre class="notranslate"><span class="pl-s1">cat_list</span> <span class="pl-c1">=</span> {<span class="pl-s">'gender'</span>, <span class="pl-s">'nationality'</span>}
<span class="pl-s1">set_cat_list</span> <span class="pl-c1">=</span> <span class="pl-k">lambda</span> <span class="pl-s1">x</span>: <span class="pl-s1">x</span>.<span class="pl-en">astype</span>(<span class="pl-s">'category'</span>) <span class="pl-k">if</span> <span class="pl-s1">x</span>.<span class="pl-s1">name</span> <span class="pl-c1">in</span> <span class="pl-s1">cat_list</span> <span class="pl-k">else</span> <span class="pl-s1">x</span>
<span class="pl-s1">dfa</span> <span class="pl-c1">=</span> <span class="pl-s1">pdf</span>.<span class="pl-en">apply</span>(<span class="pl-s1">set_cat_list</span>)

<span class="pl-c1">&gt;&gt;</span><span class="pl-c1">&gt;</span> <span class="pl-en">print</span>(<span class="pl-s">'Applied to subset: dtype={}'</span>.<span class="pl-en">format</span>(<span class="pl-s1">dfa</span>[<span class="pl-s">'gender'</span>].<span class="pl-s1">dtype</span>))
<span class="pl-v">Applied</span> <span class="pl-s1">to</span> <span class="pl-s1">subset</span>: <span class="pl-s1">dtype</span><span class="pl-c1">=</span><span class="pl-s1">object</span></pre></div>
<p dir="auto">To make sure that the problem isn't just that I'm never reaching the <code class="notranslate">x.astype('category')</code> branch of the <code class="notranslate">lambda</code> expression, I added in an alert:</p>
<div class="highlight highlight-source-python notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="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)
&gt;&gt;&gt; print('Applied to subset: dtype={}'.format(dfa['gender'].dtype))
age: False
age: False
gender: True
nationality: True
height: False
Applied to subset: dtype=object"><pre class="notranslate"><span class="pl-s1">in_cl</span> <span class="pl-c1">=</span> <span class="pl-k">lambda</span> <span class="pl-s1">x</span>: <span class="pl-s1">x</span>.<span class="pl-s1">name</span> <span class="pl-c1">in</span> <span class="pl-s1">cat_list</span>
<span class="pl-s1">set_cat_list_alert</span> <span class="pl-c1">=</span> <span class="pl-k">lambda</span> <span class="pl-s1">x</span>: (<span class="pl-en">set_cat_list</span>(<span class="pl-s1">x</span>),
                                <span class="pl-s1">sys</span>.<span class="pl-s1">stdout</span>.<span class="pl-en">write</span>(<span class="pl-s">'{}: {}<span class="pl-cce">\n</span>'</span>.<span class="pl-en">format</span>(<span class="pl-s1">x</span>.<span class="pl-s1">name</span>, <span class="pl-en">in_cl</span>(<span class="pl-s1">x</span>))))[<span class="pl-c1">0</span>]
<span class="pl-s1">dfa</span> <span class="pl-c1">=</span> <span class="pl-s1">pdf</span>.<span class="pl-en">apply</span>(<span class="pl-s1">set_cat_list_alert</span>)
<span class="pl-c1">&gt;&gt;</span><span class="pl-c1">&gt;</span> <span class="pl-en">print</span>(<span class="pl-s">'Applied to subset: dtype={}'</span>.<span class="pl-en">format</span>(<span class="pl-s1">dfa</span>[<span class="pl-s">'gender'</span>].<span class="pl-s1">dtype</span>))
<span class="pl-s1">age</span>: <span class="pl-c1">False</span>
<span class="pl-s1">age</span>: <span class="pl-c1">False</span>
<span class="pl-s1">gender</span>: <span class="pl-c1">True</span>
<span class="pl-s1">nationality</span>: <span class="pl-c1">True</span>
<span class="pl-s1">height</span>: <span class="pl-c1">False</span>
<span class="pl-v">Applied</span> <span class="pl-s1">to</span> <span class="pl-s1">subset</span>: <span class="pl-s1">dtype</span><span class="pl-c1">=</span><span class="pl-s1">object</span></pre></div>
<p dir="auto">To verify that it's not just a problem setting <em>any</em> columns as categorical, I tried setting <em>all</em> columns to categorical, which works just fine:</p>
<div class="highlight highlight-source-python notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="set_cat = lambda x: x.astype('category')
dfb = pdf.apply(set_cat)

&gt;&gt;&gt; print('Applied to whole frame: dtype={}'.format(dfb['gender'].dtype))
Applied to whole frame: dtype=category"><pre class="notranslate"><span class="pl-s1">set_cat</span> <span class="pl-c1">=</span> <span class="pl-k">lambda</span> <span class="pl-s1">x</span>: <span class="pl-s1">x</span>.<span class="pl-en">astype</span>(<span class="pl-s">'category'</span>)
<span class="pl-s1">dfb</span> <span class="pl-c1">=</span> <span class="pl-s1">pdf</span>.<span class="pl-en">apply</span>(<span class="pl-s1">set_cat</span>)

<span class="pl-c1">&gt;&gt;</span><span class="pl-c1">&gt;</span> <span class="pl-en">print</span>(<span class="pl-s">'Applied to whole frame: dtype={}'</span>.<span class="pl-en">format</span>(<span class="pl-s1">dfb</span>[<span class="pl-s">'gender'</span>].<span class="pl-s1">dtype</span>))
<span class="pl-v">Applied</span> <span class="pl-s1">to</span> <span class="pl-s1">whole</span> <span class="pl-s1">frame</span>: <span class="pl-s1">dtype</span><span class="pl-c1">=</span><span class="pl-s1">category</span></pre></div>
<p dir="auto">Finally, I tried just using a for loop to duplicate the final result, to make sure that mixed categorical / non-categorical columns can coexist like this:</p>
<div class="highlight highlight-source-python notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="dfc = pdf.copy()
for cat in cat_list:
    dfc[cat] = pdf[cat].astype('category')

&gt;&gt;&gt; print('For loop: dtype={}'.format(dfc['gender'].dtype))
For loop: dtype=category"><pre class="notranslate"><span class="pl-s1">dfc</span> <span class="pl-c1">=</span> <span class="pl-s1">pdf</span>.<span class="pl-en">copy</span>()
<span class="pl-k">for</span> <span class="pl-s1">cat</span> <span class="pl-c1">in</span> <span class="pl-s1">cat_list</span>:
    <span class="pl-s1">dfc</span>[<span class="pl-s1">cat</span>] <span class="pl-c1">=</span> <span class="pl-s1">pdf</span>[<span class="pl-s1">cat</span>].<span class="pl-en">astype</span>(<span class="pl-s">'category'</span>)

<span class="pl-c1">&gt;&gt;</span><span class="pl-c1">&gt;</span> <span class="pl-en">print</span>(<span class="pl-s">'For loop: dtype={}'</span>.<span class="pl-en">format</span>(<span class="pl-s1">dfc</span>[<span class="pl-s">'gender'</span>].<span class="pl-s1">dtype</span>))
<span class="pl-v">For</span> <span class="pl-s1">loop</span>: <span class="pl-s1">dtype</span><span class="pl-c1">=</span><span class="pl-s1">category</span></pre></div>
<p dir="auto">Is this the desired behavior?</p>
<p dir="auto">The following raises the error</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="pandas.Series([0.1, 0.2], index=[1, 2]).loc[[2, 3, 2]]"><pre class="notranslate"><code class="notranslate">pandas.Series([0.1, 0.2], index=[1, 2]).loc[[2, 3, 2]]
</code></pre></div>
<p dir="auto">whilst</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="pandas.Series([0.1, 0.2], index=[1, 2]).loc[[2, 2, 3]]"><pre class="notranslate"><code class="notranslate">pandas.Series([0.1, 0.2], index=[1, 2]).loc[[2, 2, 3]]
</code></pre></div>
<p dir="auto">does not. Or is there something invalid with this code?</p>