crosstab是pandas中处理分类变量联合分布的首选工具,它自动补零、对齐行列、支持标准化与加权,语义清晰且避免groupby+unstack的缺陷。

crosstab 是 Pandas 里做分类变量频数统计最直接的工具,不是“能用”,而是“该用它”——尤其当你需要快速看两个(或多个)离散字段的联合分布时。
为什么不用 groupby + size()?
很多人习惯先 groupby(['col_a', 'col_b']).size(),再 unstack() 拼成表格。这确实可行,但容易漏掉某类组合的零频次(默认不显示),且行列顺序难控。而 crosstab 默认保留所有唯一值、自动对齐行列、支持标准化和加权,语义更清晰。
- 缺失组合会补
0,不是直接跳过 - 列名和索引名默认来自原始字段名,无需手动重命名
- 传入
normalize='index'就能立刻算行百分比,normalize=True算整体比例
crosstab 的核心参数怎么选?
关键就三个:index、columns、values(可选)。前两者必填,决定行和列;values 只在你想做聚合(比如求均值、计数以外的统计)时才用。
- 只传两个 Series 或列名:
pd.crosstab(df['gender'], df['region'])→ 纯频数表 - 加
margins=True:末行末列自动加行/列合计 - 想按第三列加权统计?用
values=df['weight']+aggfunc='sum' - 注意:
dropna=False才会把NaN当作一个独立类别参与统计(默认是剔除的)
常见报错和静默陷阱
最常卡在类型和缺失值上,错误信息往往不直说问题在哪。
-
ValueError: arrays must all be same length:传入的index和columns长度不一致 —— 多半是其中一个是 Series,另一个是 list 且长度不对,统一用df['col']或df.col - 结果全是
0或空?检查是否用了values但没配aggfunc,此时默认用len,但若values含NaN,len会返回0 - 中文列名或特殊字符导致显示错乱?加参数
rownames=['行标签']和colnames=['列标签']显式控制名称,避免依赖原始字段名
真正麻烦的是多级索引+空值混合的场景:既要保留 NaN 类别,又要对某几列做归一化,还得导出带合并单元格的 Excel —— 这时候 crosstab 只是起点,后续得接 fillna、reindex 和 to_excel 的 merge_cells=False 控制。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











