pandas保留多重索引并计算客户分组与产品类型的相关性
解决方案
1. 保留多重索引正确导入数据
直接调用pd.DataFrame.from_dict()丢失多重索引,是因为没有将元组格式的键显式解析为MultiIndex结构,使用如下代码导入即可完整保留两层索引:
import pandas as pd import numpy as np from scipy.stats import chi2_contingency # 读取字典数据 df = pd.DataFrame.from_dict(my_data) # 将元组索引转换为命名的多重索引 df.index = pd.MultiIndex.from_tuples( df.index, names=['customer_group', 'product_type'] )
导入完成后执行df.unstack()即可得到行是客户分组、列是产品类型、值为订单数的标准宽表,不会出现维度丢失问题。
2. df.corr()不适用该场景的原因
corr()方法的作用是计算连续数值变量之间的线性相关系数,仅对数值型列生效,而customer_group和product_type均为分类变量,直接调用该方法得到的结果没有统计意义,自然会出现维度丢失的问题。
注意:单个组合的订单数最高,不能直接判定该组合相关性最高。如果某客户组本身总订单量远高于其他组、某产品本身总销量远高于其他产品,两者交叉的订单数高属于预期内的结果,不能证明两者存在特殊的购买偏好关联。
3. 分类变量相关性的正确分析方法
两个分类变量的相关性分析需要基于交叉列联表(即你unstack得到的宽表)开展,步骤如下:
- 第一步:生成标准列联表
# 提取交叉计数表,去掉多余的列名层级 contingency_table = df.unstack()['order_id']
- 第二步:卡方独立性检验判断整体相关性
使用卡方检验判断两个变量是否存在统计意义上的显著关联:
chi2_stat, p_value, degree_of_freedom, expected_counts = chi2_contingency(contingency_table)
结果判定规则:
- 若
p_value < 0.05,说明客户分组与产品购买类型存在显著相关性 - 若
p_value >= 0.05,说明没有足够证据证明两者存在关联 - 第三步:定位相关性最强的组合
卡方检验只能判断整体是否相关,要找具体的强关联组合,需要计算每个单元格的标准化皮尔逊残差:
# 计算标准化残差 std_residuals = (contingency_table - expected_counts) / np.sqrt(expected_counts)
残差的含义:
- 残差为正且数值越大:该客户组购买对应产品的偏好显著高于整体平均水平
- 残差为负且绝对值越大:该客户组购买对应产品的偏好显著低于整体平均水平
直接对std_residuals按数值排序,就能得到真正关联强度最高的组合,排除总订单量、总销量的干扰。基于你提供的样例数据计算,group_10与D的标准化残差确实为所有组合中最高,属于真实的强偏好组合,但这个结论是经过基线校准的,不是单纯因为订单数高得出的。
内容的提问来源于stack exchange,提问作者Jonas Palačionis
相关产品推荐
相关产品推荐

