Pandas中如何按列元素的集合(set)分组统计购买组合次数
实现方案与原理说明
1. 新增# of times bought列的实现方法
核心思路是将不可哈希的集合转换为可哈希、且相同集合取值一致的类型作为分组键,再配合transform将分组统计结果映射回原表每一行:
import pandas as pd # 构造原始示例数据 df = pd.DataFrame({'name':['Josh', 'Paul','Ivy','Mark'], 'orderId':[1,2,3,4], 'purchases':[['sofa','sofa','chair'], ['chair','sofa'], ['sofa','chair'], ['sofa','chair','chair']]}) # 生成可哈希的去重购买组合键:先转set去重,排序后转tuple保证相同集合的键值完全一致 df['unique_purchase_key'] = df['purchases'].apply(lambda x: tuple(sorted(set(x)))) # 按组合键分组,统计每个组合的订单数,用transform映射回原表 df['# of times bought'] = df.groupby('unique_purchase_key')['orderId'].transform('nunique') # 可选:删除临时生成的键列 df = df.drop(columns='unique_purchase_key')
运行后即可得到你需要的结果:
| name | orderId | purchases | # of times bought |
|---|---|---|---|
| Josh | 1 | [sofa, sofa, chair] | 4 |
| Paul | 2 | [chair, sofa] | 4 |
| Ivy | 3 | [sofa, chair] | 4 |
| Mark | 4 | [sofa, chair, chair] | 4 |
如果你不想新增临时列,也可以直接在groupby中传入分组键生成规则:
df['# of times bought'] = df.groupby(df['purchases'].apply(lambda x: tuple(sorted(set(x)))))['orderId'].transform('nunique')
2. Pandas不支持按set类型分组的原因
Pandas的groupby底层依赖哈希表实现分组的映射匹配,要求分组键必须是**可哈希(hashable)**的类型:
- Python中
set属于可变容器,内容修改会导致哈希值变化,因此本身是不可哈希的,无法作为哈希表的键存入分组索引,这就是你报错TypeError: unhashable type: 'set'的根本原因。 - 虽然Python支持两个
set做等值判断,但等值判断是分组的必要非充分条件,分组操作必须先通过哈希值对键做分类,再做等值校验,缺少可哈希的前提就无法完成分组逻辑。 - 你之前在Jupyter中看到的临时正确结果属于异常兼容的偶发现象,不具备可靠性,生产环境不能依赖这类输出。
内容的提问来源于stack exchange,提问作者Jonas Palačionis
相关产品推荐
相关产品推荐

