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

如何在Pandas中按ID和approved状态保留带2秒容忍度的最大值?

实现方案

以下是基于Pandas的实现步骤,完全匹配你给出的需求效果:


步骤1:数据准备与时间转换

首先将time列转换为秒数,方便后续时间差计算:

import pandas as pd

# 加载数据(如果是从CSV读取,替换为pd.read_csv("你的文件路径"))
data = [
    [1, "0:00", 10, False],
    [1, "0:01", 20, True],
    [1, "0:02", 30, True],
    [1, "0:03", 20, True],
    [1, "0:04", 40, False],
    [1, "0:05", 35, False],
    [1, "0:06", 60, False],
    [2, "0:07", 20, True],
    [2, "0:08", 30, True],
    [2, "0:09", 50, False],
    [2, "0:10", 45, False],
    [2, "0:11", 70, False],
    [2, "0:12", 62, False]
]
df = pd.DataFrame(data, columns=["id", "time", "value", "approved"])

# 转换time列为秒数
df["time_sec"] = df["time"].str.split(":").apply(lambda x: int(x[0])*60 + int(x[1]))

步骤2:按ID分组并划分数据块

以approved状态变化、时间间隔超过2秒作为新数据块的划分依据:

def create_blocks(group):
    # 标记状态变化
    group["status_change"] = group["approved"] != group["approved"].shift()
    # 标记时间间隔超过2秒的情况
    group["time_diff"] = group["time_sec"] - group["time_sec"].shift()
    group["time_diff_exceed"] = group["time_diff"] > 2
    # 生成数据块编号
    group["block"] = (group["status_change"] | group["time_diff_exceed"].fillna(False)).cumsum()
    return group

df = df.groupby("id").apply(create_blocks).reset_index(drop=True)

步骤3:分类型处理数据块

针对approved=True和approved=False的数据块分别计算最大值与对应时间:

# 标记每个数据块的approved状态
block_status = df.groupby(["id", "block"])["approved"].first().reset_index()
block_status.columns = ["id", "block", "block_approved"]
df = df.merge(block_status, on=["id", "block"], how="left")

# 处理approved=True的块:计算累计最大值及对应最早出现时间
def process_true_blocks(group):
    group["cum_max"] = group["value"].cummax()
    first_occur = group.drop_duplicates("cum_max", keep="first").set_index("cum_max")["time"]
    group["max_approved"] = group["cum_max"]
    group["max_time"] = group["cum_max"].map(first_occur)
    return group

# 处理approved=False的块:取块内第一个记录的数值与时间(首块特殊处理为NaN)
def process_false_blocks(group):
    first_val = group.iloc[0]["value"]
    first_t = group.iloc[0]["time"]
    if group["block"].iloc[0] == 1:
        group["max_approved"] = None
        group["max_time"] = None
    else:
        group["max_approved"] = first_val
        group["max_time"] = first_t
    return group

# 分组处理后合并结果
df_true = df[df["block_approved"]].groupby(["id", "block"]).apply(process_true_blocks).reset_index(drop=True)
df_false = df[~df["block_approved"]].groupby(["id", "block"]).apply(process_false_blocks).reset_index(drop=True)
df_result = pd.concat([df_true, df_false]).sort_values(["id", "time_sec"]).reset_index(drop=True)

步骤4:整理最终结果

保留需要的列并输出:

df_result = df_result[["id", "time", "value", "approved", "max_approved", "max_time"]]
print(df_result.to_string(index=False))

最终输出效果

id  time  value  approved  max_approved max_time
  1  0:00     10     False           NaN      NaN
  1  0:01     20      True          20.0     0:01
  1  0:02     30      True          30.0     0:02
  1  0:03     20      True          30.0     0:02
  1  0:04     40     False          40.0     0:04
  1  0:05     35     False          40.0     0:04
  1  0:06     60     False          40.0     0:04
  2  0:07     20      True          20.0     0:07
  2  0:08     30      True          30.0     0:08
  2  0:09     50     False          50.0     0:09
  2  0:10     45     False          50.0     0:09
  2  0:11     70     False          50.0     0:09
  2  0:12     62     False          50.0     0:09

内容的提问来源于stack exchange,提问作者mwind

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 20:50:32