SQL中Having子句的Pandas等效实现及代码转换咨询
原SQL转等效Pandas代码的正确写法
原SQL逻辑说明
这条SQL的作用是:按a和b分组,找出每个组中c值等于组内c最大值的行,最终输出a、b、组内最大c(别名MAX_c)以及DT_FIN_VERSN字段。
你现有代码的问题
groupby参数错误:应该传入列表['a','b'],而不是单独传两个字符串filter内的语法错误:max(c)要改成x['c'].max(),且要通过x['c']引用组内的c列- 没处理
MAX_c列的生成:原SQL需要输出这个派生字段,你的代码里没体现
正确实现方式
方法一:用transform生成组内最大值后筛选
这种方式最贴近SQL的逻辑,先给每行标记所在组的c最大值,再筛选符合条件的行:
# 新增MAX_c列,存储当前行所在a+b组的c最大值 df['MAX_c'] = df.groupby(['a', 'b'])['c'].transform('max') # 筛选c等于MAX_c的行,保留需要的字段 result = df[df['c'] == df['MAX_c']][['a', 'b', 'MAX_c', 'DT_FIN_VERSN']]
如果不想修改原DataFrame,可以用assign链式操作:
result = (df .assign(MAX_c=df.groupby(['a','b'])['c'].transform('max')) .query('c == MAX_c') [['a','b','MAX_c','DT_FIN_VERSN']])
方法二:用idxmax直接定位组内最大值行
如果每个组只需要保留c最大的那一行(如果有多个行c等于最大值,idxmax只会取第一个),可以用这种更高效的方式:
# 获取每个a+b组中c值最大的行的索引 max_row_indices = df.groupby(['a', 'b'])['c'].idxmax() # 根据索引提取行,同时显式生成MAX_c列 result = df.loc[max_row_indices].assign(MAX_c=lambda x: x['c'])[['a','b','MAX_c','DT_FIN_VERSN']]
注意点
- 如果同一个
a+b组内有多个行的c值等于组内最大值,方法一会保留所有符合条件的行,方法二只会保留每组的第一行最大值行,根据你的需求选择即可。
内容的提问来源于stack exchange,提问作者ssaf
相关产品推荐
相关产品推荐

