<h4 dir="auto">Code Sample, a copy-pastable example if possible</h4>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="import pandas as pd
import numpy as np
a = pd.DataFrame({'numbers': np.arange(10), 'categories': list('abcabcabcd')})
a['categories'] = a['categories'].astype('category')
b = pd.DataFrame({'numbers': np.arange(10)})

print a.dtypes
print a.categories.cat.categories
print

merged = pd.merge(a, b, left_index=True, right_index=True)

print merged.dtypes
print merged['categories'].cat.categories
print 'Merge ok!'
print

merged = pd.merge(a, b, on=['numbers'], how='left')
print merged.dtypes
try:
    print merged['categories'].cat.categories #crashes
except:
    print 'Merge not ok!'
print"><pre class="notranslate"><code class="notranslate">import pandas as pd
import numpy as np
a = pd.DataFrame({'numbers': np.arange(10), 'categories': list('abcabcabcd')})
a['categories'] = a['categories'].astype('category')
b = pd.DataFrame({'numbers': np.arange(10)})

print a.dtypes
print a.categories.cat.categories
print

merged = pd.merge(a, b, left_index=True, right_index=True)

print merged.dtypes
print merged['categories'].cat.categories
print 'Merge ok!'
print

merged = pd.merge(a, b, on=['numbers'], how='left')
print merged.dtypes
try:
    print merged['categories'].cat.categories #crashes
except:
    print 'Merge not ok!'
print
</code></pre></div>
<h4 dir="auto">Expected Output</h4>
<p dir="auto">The try block should print "categories" 's categories the same way as above, with:<br>
<code class="notranslate">Index([u'a', u'b', u'c', u'd'], dtype='object')</code></p>
<p dir="auto">However, the data type is replaced to object/string.</p>
<p dir="auto">This is not fixed by the v0.18.2 release, which fixes some of the merge issues where int's would get casted to floats when merging.</p>
<h4 dir="auto">output of <code class="notranslate">pd.show_versions()</code></h4>
<h2 dir="auto">INSTALLED VERSIONS</h2>
<p dir="auto">commit: None<br>
python: 2.7.11.final.0<br>
python-bits: 64<br>
OS: Linux<br>
OS-release: 2.6.32-431.23.3.el6.x86_64<br>
machine: x86_64<br>
processor: x86_64<br>
byteorder: little<br>
LC_ALL: None<br>
LANG: en_US.UTF-8</p>
<p dir="auto">pandas: 0.17.1<br>
nose: 1.3.7<br>
pip: 7.1.2<br>
setuptools: 20.3.1<br>
Cython: 0.23.4<br>
numpy: 1.10.4<br>
scipy: 0.16.0<br>
statsmodels: 0.6.1<br>
IPython: 4.0.1<br>
sphinx: 1.3.1<br>
patsy: 0.4.0<br>
dateutil: 2.4.2<br>
pytz: 2015.7<br>
blosc: None<br>
bottleneck: 1.0.0<br>
tables: 3.2.2<br>
numexpr: 2.4.4<br>
matplotlib: 1.5.0<br>
openpyxl: 2.2.6<br>
xlrd: 0.9.4<br>
xlwt: 1.0.0<br>
xlsxwriter: 0.7.7<br>
lxml: 3.4.4<br>
bs4: 4.4.1<br>
html5lib: None<br>
httplib2: None<br>
apiclient: None<br>
sqlalchemy: 1.0.9<br>
pymysql: None<br>
psycopg2: None<br>
Jinja2: None</p>
<p dir="auto">xref <a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="181085993" data-permission-text="Title is private" data-url="https://github.com/pandas-dev/pandas/issues/14351" data-hovercard-type="issue" data-hovercard-url="/pandas-dev/pandas/issues/14351/hovercard" href="https://github.com/pandas-dev/pandas/issues/14351">#14351</a></p>
<p dir="auto">None of the following merge operations retain the <code class="notranslate">category</code> types. Is this expected? How can I keep them?</p>
<h4 dir="auto">Merging on a <code class="notranslate">category</code> type:</h4>
<p dir="auto">Consider the following:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="A = pd.DataFrame({'X': np.random.choice(['foo', 'bar'],size=(10,)), 
                  'Y': np.random.choice(['one', 'two', 'three'], size=(10,))})
A['X'] = A['X'].astype('category')

B = pd.DataFrame({'X': np.random.choice(['foo', 'bar'],size=(10,)), 
                  'Z': np.random.choice(['jjj', 'kkk', 'sss'], size=(10,))})
B['X'] = B['X'].astype('category')"><pre class="notranslate"><code class="notranslate">A = pd.DataFrame({'X': np.random.choice(['foo', 'bar'],size=(10,)), 
                  'Y': np.random.choice(['one', 'two', 'three'], size=(10,))})
A['X'] = A['X'].astype('category')

B = pd.DataFrame({'X': np.random.choice(['foo', 'bar'],size=(10,)), 
                  'Z': np.random.choice(['jjj', 'kkk', 'sss'], size=(10,))})
B['X'] = B['X'].astype('category')
</code></pre></div>
<p dir="auto">if I do the merge, we end up with:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="&gt; pd.merge(A, B, on='X').dtypes 
X    object
Y    object
Z    object
dtype: object"><pre class="notranslate"><code class="notranslate">&gt; pd.merge(A, B, on='X').dtypes 
X    object
Y    object
Z    object
dtype: object
</code></pre></div>
<h4 dir="auto">Merging on a <code class="notranslate">non-category</code> type:</h4>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="A = pd.DataFrame({'X': np.random.choice(['foo', 'bar'],size=(10,)), 
                  'Y': np.random.choice(['one', 'two', 'three'], size=(10,))})
A['Y'] = A['Y'].astype('category')

B = pd.DataFrame({'X': np.random.choice(['foo', 'bar'],size=(10,)), 
                  'Z': np.random.choice(['jjj', 'kkk', 'sss'], size=(10,))})
B['Z'] = B['Z'].astype('category')"><pre class="notranslate"><code class="notranslate">A = pd.DataFrame({'X': np.random.choice(['foo', 'bar'],size=(10,)), 
                  'Y': np.random.choice(['one', 'two', 'three'], size=(10,))})
A['Y'] = A['Y'].astype('category')

B = pd.DataFrame({'X': np.random.choice(['foo', 'bar'],size=(10,)), 
                  'Z': np.random.choice(['jjj', 'kkk', 'sss'], size=(10,))})
B['Z'] = B['Z'].astype('category')
</code></pre></div>
<p dir="auto">if I do the merge, we end up with:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="pd.merge(A, B, on='X').dtypes
X    object
Y    object
Z    object
dtype: object"><pre class="notranslate"><code class="notranslate">pd.merge(A, B, on='X').dtypes
X    object
Y    object
Z    object
dtype: object
</code></pre></div>