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

如何用Pythonic方式在Pandas中按组检测数据超3%增长并标记

Pandas实现分组内值超3%增长的标记方案

给定如下结构的数据集:

Id date     value
x1 01-01-22  46
x1 02-01-22  46
x1 03-01-22  45.8
....
x2 03-04-22  57
X2 03-04-22  62
....

需求是:每个Id组内的value需随时间保持递减或不变(允许少量测量误差),新增一列标记当value较同组前一个时间点的值增长超过3%时为1,否则为0,同时要处理Id大小写不一致的问题(如x2和X2属于同一分组)。

解决方案

1. 数据预处理

先统一Id的大小写,避免分组错误;同时将date转换为日期格式并按Id和date排序,确保数据按时间顺序排列:

import pandas as pd

# 假设数据已加载到DataFrame df中
df['Id'] = df['Id'].str.lower()
df['date'] = pd.to_datetime(df['date'], format='%d-%m-%y')
df = df.sort_values(['Id', 'date']).reset_index(drop=True)

2. 分组生成标记列

使用groupby结合transform方法,链式完成增长比例计算与标记列生成,这是最Pythonic的写法:

df['is_invalid'] = df.groupby('Id')['value'].transform(
    lambda g: (g / g.shift(1) > 1.03).astype(int)
)

如果喜欢更连贯的链式操作,可以把预处理和标记生成整合在一起:

df = (df
      .assign(Id=lambda x: x['Id'].str.lower(),
              date=lambda x: pd.to_datetime(x['date'], format='%d-%m-%y'))
      .sort_values(['Id', 'date'])
      .assign(is_invalid=lambda x: x.groupby('Id')['value']
              .transform(lambda g: (g / g.shift(1) > 1.03).astype(int)))
      .reset_index(drop=True)
)

关键逻辑说明

  • shift(1):获取同组前一行的value值,用于计算增长比例
  • g / g.shift(1) > 1.03:判断当前值较前值的增长幅度是否超过3%
  • astype(int):将布尔判断结果转换为1(符合条件)或0(不符合条件)
  • transform方法直接返回与原DataFrame长度匹配的结果,无需额外处理索引,写法简洁优雅

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 22:20:29