如何在Pandas groupby聚合时添加类似SQL WHERE的筛选条件?
Pandas实现GroupBy前的筛选(对应SQL WHERE子句)
要实现你需要的SQL WHERE子句效果,核心逻辑是先筛选出符合条件的行,再执行分组聚合(区别于聚合后过滤的HAVING逻辑)。以下是具体实现步骤:
1. 构造示例数据
import pandas as pd import numpy as np # 构造你的示例DataFrame df = pd.DataFrame({ 'id': [1, 1, 1], 'c1': [1, 2, 3], 'c2': [2, 3, 4], 'c3': [3, 4, 5] })
2. 先应用筛选条件
使用between()方法匹配SQL的BETWEEN逻辑,结合布尔索引筛选符合条件的行:
# 筛选满足所有条件的行:c1∈[2,3] 且 c2∈[2,3] 且 c3∈[2,3] filtered_df = df[ (df['c1'].between(2, 3)) & (df['c2'].between(2, 3)) & (df['c3'].between(2, 3)) ]
筛选后的filtered_df仅保留符合条件的行:
id c1 c2 c3 0 1 2 3 3
3. 对筛选后的数据分组聚合
直接在筛选后的DataFrame上执行groupby和agg,即可得到你想要的结果:
grouped_df = filtered_df.groupby(['id']).agg( gc1=('c1', np.min), gc2=('c2', np.min), gc3=('c3', np.min) ).reset_index()
最终结果
id gc1 gc2 gc3 0 1 2 2 3
补充说明
如果你的需求是不同聚合列使用不同的筛选条件(比如c1的最小值只考虑c1>2的行,c2的最小值只考虑c2<4的行),可以自定义聚合函数:
def min_with_filter(series, low, high): return series[(series >= low) & (series <= high)].min() grouped_df = df.groupby(['id']).agg( gc1=('c1', lambda x: min_with_filter(x, 2, 3)), gc2=('c2', lambda x: min_with_filter(x, 2, 3)), gc3=('c3', lambda x: min_with_filter(x, 2, 3)) ).reset_index()
这种方式不需要提前筛选整行,而是针对每列单独应用筛选后再聚合,结果和之前一致,但性能略低于先整行筛选的方式(适合复杂场景)。
内容的提问来源于stack exchange,提问作者kiritowow
相关产品推荐
相关产品推荐

