如何解读pandas中crosstab生成的四维及更高维列联表?
高维列联表异常问题原因及解决方案
问题本质
- 组合缺失:
pd.crosstab默认仅保留数据中实际存在的列维度组合,没有对应样本的零值组合会被直接过滤,不会出现在输出结果中 - 标签顺序反转:默认维度取值的排序规则为「首次出现顺序」,而非数值大小顺序,你观察到的lp3标签顺序反转,就是因为数据集中lp3=1的组合先出现
固定输出格式的实现方法
如果需要输出所有理论布尔组合、且固定取值顺序为0在前1在后,先将参与列联表的维度列显式转为指定分类范围的分类类型,再调用pd.crosstab时添加dropna=False参数即可:
import pandas as pd df = pd.DataFrame({"la":[0,1,1,0,1], "lp1": [1,0,1,0,0], "lp2":[1,1,0,0,1], "lp3":[0,0,1,1,1], "lp4":[0,1,1,0,0]}) # 批量将lp列转为固定分类范围的分类类型,固定取值顺序 lp_cols = ["lp1", "lp2", "lp3"] for col in lp_cols: df[col] = pd.Categorical(df[col], categories=[0, 1]) # 生成包含所有理论组合的三维列联表 cross_3d = pd.crosstab(index=df["la"], columns=[df[c] for c in lp_cols], dropna=False)
运行上述代码后输出的列联表会包含所有2^3=8种lp维度组合,且所有维度的取值顺序固定为0、1。
高维列联表解读规则
处理后的输出为多层列索引的DataFrame结构,解读逻辑如下:
- 行索引对应
la的取值 - 列索引从外层到内层,依次对应你传入
columns参数的变量顺序(示例中为lp1→lp2→lp3) - 单元格的数值即为满足「行索引la取值 + 列索引各层对应变量取值」的样本计数
例如列索引为(0, 1, 0)、行索引为1的单元格值,就是la=1、lp1=0、lp2=1、lp3=0的样本出现次数。
高维场景更友好的替代方案
如果觉得多层列索引阅读成本高,可以改用groupby生成长表格式的统计结果,每个维度组合单独占一行,更易排查:
# 生成长表格式计数结果,count列为对应组合的样本数 count_long = df.groupby(["la", "lp1", "lp2", "lp3"], dropna=False).size().reset_index(name="count")
内容的提问来源于stack exchange,提问作者João Diogo Duarte
相关产品推荐
相关产品推荐

