基于条件实现列转行聚合的简易数据透视表操作方法
实现方案
这是非常典型的宽表转长表+条件聚合场景,核心逻辑分三步即可:
- 先将所有二进制标识列从列维度转换为行维度
- 过滤掉二进制列取值为0的无效记录
- 按转换后的条件维度分组,对所有聚合字段求和
不同工具栈都有极简的实现方式,不需要写复杂逻辑:
SQL 实现(适配绝大多数数据库、数仓引擎)
优先用UNPIVOT语法做行列转换,代码最简洁:
SELECT Cohort, SUM(agg_1) AS agg_1, SUM(agg_2) AS agg_2 FROM ( SELECT * FROM 你的输入表 UNPIVOT ( is_match FOR Cohort IN (Condition_1, Condition_2, Condition_3) ) t ) t2 WHERE is_match = 1 GROUP BY Cohort;
如果使用的引擎不支持UNPIVOT,直接用UNION ALL逐条件统计也可以,逻辑直白不需要记特殊语法:
SELECT 'Condition_1' AS Cohort, SUM(agg_1) agg_1, SUM(agg_2) agg_2 FROM 你的输入表 WHERE Condition_1 = 1 UNION ALL SELECT 'Condition_2' AS Cohort, SUM(agg_1) agg_1, SUM(agg_2) agg_2 FROM 你的输入表 WHERE Condition_2 = 1 UNION ALL SELECT 'Condition_3' AS Cohort, SUM(agg_1) agg_1, SUM(agg_2) agg_2 FROM 你的输入表 WHERE Condition_3 = 1;
Python Pandas 实现
用melt方法做宽表转长表,链式调用即可完成全流程:
import pandas as pd # 读取/构造原始输入表 df = pd.DataFrame({ "Condition_1": [0,1,0,0], "Condition_2": [1,1,0,1], "Condition_3": [1,1,1,0], "agg_1": [50,50,50,50], "agg_2": [100,100,100,100] }) # 核心处理逻辑 result = ( df.melt( id_vars=["agg_1", "agg_2"], value_vars=[col for col in df.columns if col.startswith("Condition_")], var_name="Cohort" ) .query("value == 1") .groupby("Cohort", as_index=False)[["agg_1", "agg_2"]] .sum() )
优化提示:如果二进制条件列数量很多,不需要手动枚举列名,用列名前缀/匹配规则自动筛选即可,上面Pandas代码已经做了自动适配,SQL场景可以配合动态SQL自动生成待转换的列列表,几十上百个条件列也能几行代码处理完。
运行后得到的结果和示例给出的期望输出完全一致。
内容的提问来源于stack exchange,提问作者Kbbm
相关产品推荐
相关产品推荐

