Repository: pandas-dev/pandas

Issue:
Uninteded cast from int to float in pd.crosstab with different indexes
#### Code Sample, a copy-pastable example if possible

```python
In [2]: pd.crosstab(pd.Series([1,2,3]), pd.Series([1,2]))
Out[2]: 
col_0  1.0  2.0
row_0          
1        1    0
2        0    1
```
#### Problem description

The shorter series gets casted to float before the computation, which one would not expect, given that index elements with at least one missing value are discarded in the computation..

#### Expected Output
The same as

```python
In [3]: pd.crosstab(pd.Series([1,2]), pd.Series([1,2]))
Out[3]: 
col_0  1  2
row_0      
1      1  0
2      0  1
```

#### Output of ``pd.show_versions()``

<details>
INSTALLED VERSIONS
------------------
commit: ea487fc9b197285f25b066450c46fc456db09e2a
python: 3.5.3.final.0
python-bits: 64
OS: Linux
OS-release: 4.9.0-3-amd64
machine: x86_64
processor: 
byteorder: little
LC_ALL: None
LANG: it_IT.UTF-8
LOCALE: it_IT.UTF-8

pandas: 0.21.0.dev+258.gea487fc9b.dirty
pytest: 3.0.6
pip: 9.0.1
setuptools: None
Cython: 0.25.2
numpy: 1.12.1
scipy: 0.19.0
xarray: None
IPython: 5.1.0.dev
sphinx: 1.5.6
patsy: 0.4.1
dateutil: 2.6.0
pytz: 2017.2
blosc: None
bottleneck: 1.2.1
tables: 3.3.0
numexpr: 2.6.1
feather: 0.3.1
matplotlib: 2.0.2
openpyxl: None
xlrd: 1.0.0
xlwt: 1.1.2
xlsxwriter: 0.9.6
lxml: None
bs4: 4.5.3
html5lib: 0.999999999
sqlalchemy: 1.0.15
pymysql: None
psycopg2: None
jinja2: 2.9.6
s3fs: None
pandas_gbq: None
pandas_datareader: 0.2.1
</details>



Discussion:

Resolving patch:
diff --git a/pandas/core/reshape/pivot.py b/pandas/core/reshape/pivot.py
--- a/pandas/core/reshape/pivot.py
+++ b/pandas/core/reshape/pivot.py
@@ -6,6 +6,7 @@
 from pandas import Series, DataFrame, MultiIndex, Index
 from pandas.core.groupby import Grouper
 from pandas.core.reshape.util import cartesian_product
+from pandas.core.index import _get_combined_index
 from pandas.compat import range, lrange, zip
 from pandas import compat
 import pandas.core.common as com
@@ -493,6 +494,13 @@ def crosstab(index, columns, values=None, rownames=None, colnames=None,
     rownames = _get_names(index, rownames, prefix='row')
     colnames = _get_names(columns, colnames, prefix='col')
 
+    obs_idxes = [obj.index for objs in (index, columns) for obj in objs
+                 if hasattr(obj, 'index')]
+    if obs_idxes:
+        common_idx = _get_combined_index(obs_idxes, intersect=True)
+    else:
+        common_idx = None
+
     data = {}
     data.update(zip(rownames, index))
     data.update(zip(colnames, columns))
@@ -503,20 +511,21 @@ def crosstab(index, columns, values=None, rownames=None, colnames=None,
     if values is not None and aggfunc is None:
         raise ValueError("values cannot be used without an aggfunc.")
 
+    df = DataFrame(data, index=common_idx)
     if values is None:
-        df = DataFrame(data)
         df['__dummy__'] = 0
-        table = df.pivot_table('__dummy__', index=rownames, columns=colnames,
-                               aggfunc=len, margins=margins,
-                               margins_name=margins_name, dropna=dropna)
-        table = table.fillna(0).astype(np.int64)
-
+        kwargs = {'aggfunc': len, 'fill_value': 0}
     else:
-        data['__dummy__'] = values
-        df = DataFrame(data)
-        table = df.pivot_table('__dummy__', index=rownames, columns=colnames,
-                               aggfunc=aggfunc, margins=margins,
-                               margins_name=margins_name, dropna=dropna)
+        df['__dummy__'] = values
+        kwargs = {'aggfunc': aggfunc}
+
+    table = df.pivot_table('__dummy__', index=rownames, columns=colnames,
+                           margins=margins, margins_name=margins_name,
+                           dropna=dropna, **kwargs)
+
+    # GH 17013:
+    if values is None and margins:
+        table = table.fillna(0).astype(np.int64)
 
     # Post-process
     if normalize is not False:


Test patch:
diff --git a/pandas/tests/reshape/test_pivot.py b/pandas/tests/reshape/test_pivot.py
--- a/pandas/tests/reshape/test_pivot.py
+++ b/pandas/tests/reshape/test_pivot.py
@@ -1058,6 +1058,22 @@ def test_crosstab_ndarray(self):
         assert result.index.name == 'row_0'
         assert result.columns.name == 'col_0'
 
+    def test_crosstab_non_aligned(self):
+        # GH 17005
+        a = pd.Series([0, 1, 1], index=['a', 'b', 'c'])
+        b = pd.Series([3, 4, 3, 4, 3], index=['a', 'b', 'c', 'd', 'f'])
+        c = np.array([3, 4, 3])
+
+        expected = pd.DataFrame([[1, 0], [1, 1]],
+                                index=Index([0, 1], name='row_0'),
+                                columns=Index([3, 4], name='col_0'))
+
+        result = crosstab(a, b)
+        tm.assert_frame_equal(result, expected)
+
+        result = crosstab(a, c)
+        tm.assert_frame_equal(result, expected)
+
     def test_crosstab_margins(self):
         a = np.random.randint(0, 7, size=100)
         b = np.random.randint(0, 3, size=100)