You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 01:17:37