如何在Pandas中按target分组,筛选满足m2且无前置m1的首行
需求实现:按组筛选符合条件的DataFrame行
需要实现以下需求:在给定的Pandas DataFrame中,按target列分组,为每个组筛选出第一个满足m2掩码条件的行,但前提是该组中此行列之前没有任何行满足m1掩码条件。最终需返回所有符合条件的行中在原DataFrame里最早出现的那一行。
输入数据
DataFrame定义
import pandas as pd df = pd.DataFrame( { 'close': [109, 109, 105, 110, 105, 120, 120, 11, 90, 100], 'high': [110, 110, 108, 108, 115, 122, 123, 1120, 1000, 300], 'target': [107, 107, 107, 107, 107, 124, 124, 500, 500, 500] } )
掩码定义
m1 = ( (df.high > df.target) & (df.close > df.target) ) m2 = ( (df.high > df.target) & (df.close < df.target) )
预期输出
close high target 7 11 1120 500
规则说明
- 按
target列分组; - 仅当组内当前行之前没有任何行匹配
m1时,才选取该组中第一个匹配m2的行。 - 示例说明:
- target=107组:存在匹配m2的行,但该行之前有匹配m1的行,因此跳过该组;
- target=124组:无匹配m2的行,跳过;
- target=500组:存在匹配m2的行,且该行之前无匹配m1的行,符合条件。
- 最终返回所有符合条件的行中在原DataFrame中最早出现的那一行。
我的尝试代码
# attmpt 1 df['a'] = m1.cummax() df['b'] = m2.cummax() # attempt 2 out = df[m2.cumsum().eq(1) & m2]
解决方案
可以通过分组累积标记+筛选的方式实现需求:
# 为每组计算累积的m1标记:组内当前行及之前是否出现过m1匹配 df['has_m1_before'] = df.groupby('target')[m1].cummax() # 筛选满足m2且组内之前无m1的行,再取每个组的第一个符合条件的行 candidates = df[(m2) & (~df['has_m1_before'])].groupby('target').first() # 从候选行中取原DataFrame中最早出现的那一行 result = candidates.sort_index().head(1) print(result)
输出结果:
close high target target 500 11 1120 500
也可以用分组apply的方式实现逻辑:
def filter_group(group): # 找到组内第一个m2匹配的行索引 first_m2_idx = group[m2].idxmax() if any(group[m2]) else None if first_m2_idx is None: return pd.Series() # 检查该行之前是否有m1匹配 has_m1_before = group.loc[:first_m2_idx, m1].any() if not has_m1_before: return group.loc[first_m2_idx] # 应用分组筛选,取最早出现的符合条件的行 result = df.groupby('target').apply(filter_group).dropna().sort_index().head(1) print(result)
内容的提问来源于stack exchange,提问作者AmirX
相关产品推荐
相关产品推荐

