如何用更Pythonic的方式实现SQL的MAX+CASE WHEN逻辑?
Python实现SQL聚合透视逻辑
原SQL的核心逻辑是:按ID分组,若该ID下存在Yes=1的记录则标记Yes,否则为空;同理处理No列,最终生成每个ID仅出现一次的透视结果。以下是几种符合Python风格的pandas实现方案:
方法1:分组前转换值再取最大值
先将原数据中的1替换为对应标识字符串,其余设为空值,再按ID分组取最大值(自动保留非空标识):
import pandas as pd # 转换Yes/No列的数值为目标字符串 df['Yes'] = df['Yes'].map({1: 'Yes'}).astype('string') df['No'] = df['No'].map({1: 'No'}).astype('string') # 按ID分组聚合,取各列最大值(保留非空值) result = df.groupby('ID', as_index=False)[['Yes', 'No']].max()
方法2:分组时直接判断聚合
无需提前修改原数据,在聚合阶段直接判断该ID下是否存在符合条件的记录:
import pandas as pd result = df.groupby('ID', as_index=False).agg( Yes=('Yes', lambda x: 'Yes' if (x == 1).any() else pd.NA), No=('No', lambda x: 'No' if (x == 1).any() else pd.NA) )
方法3:使用透视表实现
借助pivot_table快速生成透视结果,聚合逻辑与前两种一致:
import pandas as pd result = df.pivot_table( index='ID', values=['Yes', 'No'], aggfunc=lambda x: 'Yes' if (x == 1).any() else pd.NA ).reset_index() # 修正No列的聚合结果 result['No'] = df.groupby('ID')['No'].apply(lambda x: 'No' if (x == 1).any() else pd.NA)
以上三种方法均能实现原SQL的效果,处理多月份重复数据时会自动按ID去重,最终每个ID仅保留一行结果。
内容的提问来源于stack exchange,提问作者Tinkinc
相关产品推荐
相关产品推荐

