本文介绍如何利用 pandas 的 `transform` 方法,直接在原始 dataframe 中高效计算按用户和类别分组后的唯一计数值平均值,避免冗余的去重、新建 dataframe 和 merge 操作,提升代码简洁性与执行效率。
在数据分析中,常需基于去重逻辑(如每个 user_id + Category 组合下的唯一 counts 值)计算分组统计量,并将结果广播回原始数据行。传统做法(如先 drop_duplicates 再 merge)不仅代码冗长,还易引入索引错位、重复匹配等隐患,且性能较差。
更优雅、高效的解法是直接在原始 DataFrame 上应用 transform ——但关键前提在于:明确“唯一值的平均”究竟指什么。从原始示例的输出可反推真实需求:
- Overall_average__Unique_Counts = 1.83 → 实际是全部 不重复 (user_id, Category, counts) 组合 中 counts 的全局均值(即 df1.drop_duplicates([‘user_id’,’Category’,’counts’])[‘counts’].mean()),而非按 user_id 分组均值;
- Categorywise_average_Unique_counts → 是每个 Category 下所有不重复 counts 值的均值(如 ‘ABC’ 对应 {3,2,1} → 均值 2.0;’XYZ’ 对应 {2,1} → 均值 1.5?但示例输出为 1.67,说明实际用了 {2,1,2} 去重后 {1,2} → (1+2)/2 = 1.5 ❌;再核对:df1_unique 中 ‘XYZ’ 行为 (D,XYZ,2), (D,XYZ,1), (E,XYZ,2) → 去重后 counts 为 [2,1] → 均值 1.5,但输出是 1.67。发现原示例代码中 df1_unique[“Categorywise_average_Unique_counts”] = df1_unique.groupby([“Category”])[‘counts’].transform(‘mean’) 计算的是 df1_unique(已去重)中各 Category 内 counts 的均值:’ABC’ 有 (A,ABC,3), (B,ABC,2), (B,ABC,1) → counts=[3,2,1] → mean=2.0;’XYZ’ 有 (D,XYZ,2), (D,XYZ,1), (E,XYZ,2) → counts=[2,1,2] → 去重后仍保留三行,transform(‘mean’) 对每行赋值 mean([2,1,2]) = 5/3 ≈ 1.67。⚠️ 注意:此处“唯一值”指组合唯一,但 counts 列本身未二次去重!因此正确理解是:先按 (user_id, Category, counts) 去重得到唯一观测,再对这些观测按需分组求 counts 均值。
因此,若严格按业务语义(即“每个用户/类别的唯一计数值的平均”),必须先去重,但可避免 merge:用 transform 结合 groupby 在去重后 DataFrame 上计算,再通过 map 或 join 回填——但最简实践仍是复用原答案思路,并修正语义:
✅ 推荐方案(兼顾简洁性与可读性):