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

Pandas时序DataFrame按列值筛选:分组保留首个正值后数据

筛选多索引分组Pandas DataFrame:保留首个value>0时间点后的所有数据

咱先来明确需求:给每个id分组,找出每组里时序上第一个value大于0的记录,然后把从这个记录开始往后的所有数据都保留下来。先看你提供的示例(我猜可能输入里第一行的value是笔误,应该是0?不然输出和需求对不上,不过咱先按逻辑来拆解)。

步骤1:准备示例数据

先把你给的输入数据用Pandas构造出来:

import pandas as pd

data = {
    'id': [1, 1, 1, 1, 1],
    'timestamp': ['2001-01-01', '2001-10-01', '2001-10-02', '2001-10-03', '2001-10-04'],
    'date': ['2001-05-01']*5,
    'value': [1, 0, 1, 0, 1]
}
df = pd.DataFrame(data)
# 先把timestamp转成日期格式,保证时序排序正确
df['timestamp'] = pd.to_datetime(df['timestamp'])

步骤2:核心解决方案

要实现需求,关键是给每个分组标记出哪些行需要保留。这里用groupby + transform + cummax的组合最简洁:

  1. 先按id和timestamp排序,确保时序是从早到晚的(这一步非常重要,不然找“第一个”会出错)
  2. 对每个id分组,生成一个布尔标记:从第一个value>0的位置开始,后面所有行都标记为True
  3. 筛选标记为True的行,得到结果

代码如下:

# 1. 按id和timestamp排序,保证时序正确
df_sorted = df.sort_values(['id', 'timestamp'])

# 2. 生成保留标记:cummax会把第一个True之后的所有元素都保持为True
df_sorted['keep'] = df_sorted.groupby('id')['value'].transform(lambda x: (x > 0).cummax())

# 3. 筛选并去掉临时列
result = df_sorted[df_sorted['keep']].drop('keep', axis=1)

print(result)

解释为什么用cummax

(x > 0)会给每个分组生成一个布尔数组,比如示例里的分组id=1会得到[True, False, True, False, True]。而cummax()(累积最大值)会把第一个True之后的所有元素都变成True,也就是[True, True, True, True, True]——这时候筛选出来的就是从第一个value>0开始的所有数据。

如果你的示例输入里第一行的value其实是0(这样才符合期望输出),那(x>0)会得到[False, False, True, False, True],cummax()后变成[False, False, True, True, True],筛选出来的就是后三行,和你要的期望输出完全一致。

扩展:如果是多索引的情况

如果你的DataFrame已经是id和timestamp的多索引,那处理逻辑类似,只需要调整分组方式:

# 假设df是多索引,索引为['id', 'timestamp']
df['keep'] = df.groupby(level='id')['value'].transform(lambda x: (x > 0).cummax())
result = df[df['keep']].drop('keep', axis=1)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 13:27:50