Code Sample, a copy-pastable example if possible

s = pd.Series(np.random.randint(0, 10, 1000, dtype=np.int64))
df = pd.crosstab(s.shift(1), s)
print(df.index.dtype)
print(df.columns.dtype)

Problem description

Outputs:

dtype('float64')
dtype('int64')

Maybe both the index and columns keep the original dtype of the series.

For documentation-related issues, you can check the latest versions of the docs on master here:

https://pandas-docs.github.io/pandas-docs-travis/

If the issue has not been resolved there, go ahead and file it in the issue tracker.

Expected Output

dtype('int64')
dtype('int64')

Output of pd.show_versions()

INSTALLED VERSIONS ------------------ commit: None python: 3.6.3.final.0 python-bits: 64 OS: Darwin OS-release: 16.7.0 machine: x86_64 processor: i386 byteorder: little LC_ALL: en_US.UTF-8 LANG: en_US.UTF-8 LOCALE: en_US.UTF-8 pandas: 0.20.3 pytest: 3.2.1 pip: 9.0.1 setuptools: 36.5.0 Cython: 0.26 numpy: 1.13.3 scipy: 1.0.0 xarray: 0.9.6 IPython: 6.1.0 sphinx: 1.6.3 patsy: 0.4.1 dateutil: 2.6.1 pytz: 2017.2 blosc: None bottleneck: 1.2.1 tables: 3.4.2 numexpr: 2.6.2 feather: None matplotlib: 2.0.2 openpyxl: 2.4.8 xlrd: 1.0.0 xlwt: None xlsxwriter: None lxml: 3.8.0 bs4: 4.6.0 html5lib: 0.9999999 sqlalchemy: 1.1.13 pymysql: 0.7.11.None psycopg2: 2.7.3 (dt dec pq3 ext lo64) jinja2: 2.9.6 s3fs: None pandas_gbq: None pandas_datareader: 0.5.0

Comment From: jreback

This is correct

introduces nans and so dtype changes to float

In [5]: s.shift(1).dtype
Out[5]: dtype('float64')

you should fill them and astype if you want.

In [4]: s = pd.Series(np.random.randint(0, 10, 1000, dtype=np.int64))
   ...: df = pd.crosstab(s.shift(1).fillna(0).astype(int), s)
   ...: print(df.index.dtype)
   ...: print(df.columns.dtype)
   ...: 
int64
int64