The same, if in pivot_table use aggfunc=len and fill_value=0 :
pd.crosstab(df['Col X'], df['Col Y']) pd.pivot_table(df, index=['Col X'], columns=['Col Y'], aggfunc=len, fill_value=0)
EDIT: There is a big difference:
By default, aggfunc different: pivot_table - np.mean , crosstab - len .
The margins_name parameter is located only in pivot_table .
In pivot_table you can use Grouper for index and columns keywords.
I think if you just need a frequency table, the crosstab function crosstab better.
source share