crosstab para tabelas de frequência
Calcule uma tabulação cruzada de frequências ou proporções de duas colunas categóricas com pd.crosstab.
crosstab para tabelas de frequência é uma aula grátis de Pandas & NumPy Academy no CoddyKit. Esta é a aula 4 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de Pandas & NumPy Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de Pandas & NumPy Academy inclui 4 aulas no total.
Partes desta aula ainda não foram traduzidas e aparecem em inglês.
What Is a Crosstab?
A cross-tabulation (crosstab) counts how many times each combination of values from two (or more) categorical variables appears in a dataset. It is a special case of pivot table designed specifically for counting. Pandas provides pd.crosstab() as a concise way to compute these frequency tables without needing to call groupby() or pivot_table() explicitly.
Basic crosstab() Call
The minimal pd.crosstab(index, columns) call takes two array-like inputs (typically DataFrame columns) and returns a frequency table. Rows correspond to unique values in the first argument and columns correspond to unique values in the second. Each cell contains the count of rows where both values co-occur in the original data.
import pandas as pd
df = pd.DataFrame({
'gender': ['M', 'F', 'M', 'F', 'M', 'F', 'M'],
'product': ['A', 'A', 'B', 'B', 'A', 'B', 'B']
})
ct = pd.crosstab(df['gender'], df['product'])
print(ct)
# product A B
# gender
# F 1 2
# M 2 2Customising Row and Column Names
Use the rownames and colnames parameters to give the row and column axis meaningful names in the output, overriding the default Series names. This is useful when the raw column names in your DataFrame are not self-explanatory in the context of the table being produced.
ct = pd.crosstab(
df['gender'], df['product'],
rownames=['Customer Gender'],
colnames=['Purchased Product']
)
print(ct)
# Purchased Product A B
# Customer Gender
# F 1 2
# M 2 2Adding Margins (Row and Column Totals)
Pass margins=True to include a row and column totalling all values. The margin label defaults to 'All' but can be customised with margins_name. The margins row shows the total count per column, the margins column shows the total count per row, and the bottom-right cell shows the grand total.
ct = pd.crosstab(df['gender'], df['product'],
margins=True, margins_name='Total')
print(ct)
# product A B Total
# gender
# F 1 2 3
# M 2 2 4
# Total 3 4 7Normalising to Proportions
Pass the normalize parameter to convert counts to proportions. normalize=True or normalize='all' divides by the grand total. normalize='index' computes row proportions (each row sums to 1.0). normalize='columns' computes column proportions (each column sums to 1.0). Proportions are more informative than raw counts when group sizes differ.
# Row proportions: what fraction of each gender bought each product?
print(pd.crosstab(df['gender'], df['product'], normalize='index').round(2))
# product A B
# gender
# F 0.33 0.67
# M 0.50 0.50
# All proportions: each cell as fraction of grand total
print(pd.crosstab(df['gender'], df['product'], normalize=True).round(2))Aggregating Values Instead of Counting
By default, crosstab counts rows. You can instead aggregate a numeric column by passing values and aggfunc parameters — similar to pivot_table(). For example, compute total revenue for each gender-product combination. This makes crosstab nearly equivalent to pivot_table but with a slightly more concise syntax for the frequency table use case.
df['revenue'] = [100, 80, 150, 120, 200, 90, 130]
# Sum revenue by gender and product instead of counting
ct_rev = pd.crosstab(
df['gender'], df['product'],
values=df['revenue'],
aggfunc='sum'
)
print(ct_rev)
# product A B
# gender
# F 80 210
# M 300 280Multi-Level Crosstab
Pass a list to index or columns to create a crosstab with multiple levels on the rows or columns. The result has a MultiIndex, giving you a more granular breakdown. For example, cross-tabulating by gender and region on the rows against product on the columns shows every gender-region-product combination.
df['region'] = ['East', 'West', 'East', 'West', 'East', 'East', 'West']
ct_multi = pd.crosstab(
[df['gender'], df['region']],
df['product'],
margins=True
)
print(ct_multi)
# product A B All
# gender region
# F East 0 1 1
# West 1 1 2
# M East 2 1 3
# West 0 1 1
# All 3 4 7crosstab() vs pivot_table()
pd.crosstab() and pd.pivot_table() overlap significantly. crosstab is optimised for frequency counting and takes array-like inputs directly (not a DataFrame), making it slightly more concise for quick tabulations. pivot_table operates on a DataFrame and supports any aggregation function natively. For pure counting tasks, crosstab is the idiomatic choice; for aggregating numeric values, prefer pivot_table.
# crosstab (more concise for counting)
print(pd.crosstab(df['gender'], df['product']))
# Equivalent pivot_table
print(pd.pivot_table(df, index='gender', columns='product',
aggfunc='size', fill_value=0))
# Both produce the same resultChi-Squared Test Preparation
A crosstab is the standard input for a chi-squared test of independence, which tests whether two categorical variables are statistically related. The scipy.stats.chi2_contingency() function accepts a crosstab array directly. This is one of the most common uses of crosstab in statistical data analysis — you compute the table and then test it in one workflow.
from scipy import stats
ct = pd.crosstab(df['gender'], df['product'])
# Convert to numpy array for scipy
chi2, p, dof, expected = stats.chi2_contingency(ct.values)
print(f'Chi2: {chi2:.2f}')
print(f'P-value: {p:.4f}')
print(f'Degrees of freedom: {dof}')
# p > 0.05 means no significant associationVisualising Crosstab as a Heatmap
Crosstabs with many categories are hard to interpret as raw numbers. Visualising them as a heatmap with sns.heatmap() makes patterns immediately visible — high-frequency cells appear as bright colours. Pass the normalised version to show proportions rather than raw counts, and use annot=True to display the values in each cell.
import seaborn as sns
import matplotlib.pyplot as plt
ct_norm = pd.crosstab(df['gender'], df['product'], normalize='index')
# sns.heatmap(ct_norm, annot=True, fmt='.0%', cmap='Blues')
# plt.title('Purchase Rate by Gender and Product')
# plt.tight_layout()
# plt.show()
print('Normalised crosstab ready for heatmap:')
print(ct_norm.round(2))Practical Example: Survey Analysis
A complete crosstab workflow: load survey data, compute frequency tables between demographic and response variables, normalise by rows to get response rates, and identify any strong patterns. This is the standard analysis pipeline in market research, A/B testing, and user segmentation, and it can be completed in under 10 lines of Pandas code.
# Simulate a survey dataset
survey = pd.DataFrame({
'age_group': ['18-25', '26-35', '18-25', '36-45', '26-35', '36-45'],
'satisfaction': ['High', 'Low', 'High', 'Medium', 'High', 'Low']
})
ct = pd.crosstab(survey['age_group'], survey['satisfaction'],
margins=True, margins_name='Total')
print(ct)
rates = pd.crosstab(survey['age_group'], survey['satisfaction'],
normalize='index').round(2)
print(rates)Quick Check
Test your understanding of pd.crosstab for frequency tables from this lesson.
Lesson Recap
In this lesson you learned: pd.crosstab() computes frequency counts for combinations of two categorical variables; normalize converts counts to row, column, or total proportions; margins=True adds row and column totals; and crosstab output is directly compatible with chi-squared tests and heatmap visualisations. Next up we work with time series data using DatetimeIndex and period ranges.
Perguntas Frequentes
A aula “crosstab para tabelas de frequência” é grátis?
Sim — o texto completo de “crosstab para tabelas de frequência” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de Pandas & NumPy Academy, atualize para CoddyKit PRO. O curso de Pandas & NumPy Academy inclui 4 aulas no total.
O que vou aprender em “crosstab para tabelas de frequência”?
Calcule uma tabulação cruzada de frequências ou proporções de duas colunas categóricas com pd.crosstab. Você pratica Pandas & NumPy Academy com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.
Preciso ter experiência prévia para começar Pandas & NumPy Academy?
Nenhuma experiência prévia é necessária. Pandas & NumPy Academy no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 4 de 4.
Quanto tempo leva a aula “crosstab para tabelas de frequência”?
A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.
Posso escrever e executar código nesta aula de Pandas & NumPy Academy?
Sim. Cada aula de Pandas & NumPy Academy inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.
Todas as aulas deste curso
- pivot_table: tabulação cruzada
- melt: do formato largo ao longo
- stack e unstack com MultiIndex
- crosstab para tabelas de frequência