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

Pandas按ID和日期分组筛选相邻Value差值≤1的连续行并计算均值

完整实现方案

核心逻辑是先按ID+Date分组,给组内连续符合「相邻差值绝对值≤1」条件的行打相同的段标识,再筛选每组最长段计算平均值即可,完整代码如下:

import pandas as pd

# 1. 计算组内相邻Value的差值绝对值
df['diff'] = abs(df.groupby(['ID', 'Date'])['Value'].diff())

# 2. 给连续符合条件的行打段标识:组内只要出现差值>1的情况,段号+1
df['block'] = df.groupby(['ID', 'Date'])['diff'].apply(lambda x: (x.fillna(0) > 1).cumsum())

# 3. 统计每个段的长度和平均值
block_info = df.groupby(['ID', 'Date', 'block'])['Value'].agg(
    block_len = 'size',
    value_avg = 'mean'
).reset_index()

# 4. 按ID+Date分组,取长度最长的段的平均值,多个最长段默认取第一个
result = block_info.sort_values(
    by = ['ID', 'Date', 'block_len'], 
    ascending = [True, True, False]
).drop_duplicates(
    subset = ['ID', 'Date'], 
    keep = 'first'
)[['ID', 'Date', 'value_avg']].reset_index(drop=True)
逻辑说明
  • 你之前的代码问题出在计算累计和cumsum()时没有限制在ID+Date分组内,会出现跨组的段标识错乱,导致计数错误
  • 首行的差值为NaN,我们用fillna(0)处理,保证首行默认属于第一个有效段
  • 如果需要处理多个等长最长段的情况,修改drop_duplicates的keep参数即可,比如keep='last'取最后一个最长段
测试验证

可以用以下测试数据验证逻辑正确性:

# 测试数据
data = {
    'ID': [1,1,1,1,2,2,2],
    'Date': ['2024-01-01']*4 + ['2024-01-01']*3,
    'Value': [1,2,3,5,4,5,7]
}
df = pd.DataFrame(data)

运行后得到的result结果为:

IDDatevalue_avg
12024-01-012.0
22024-01-014.5

符合预期:ID1的最长连续段是[1,2,3]、均值2,ID2的最长连续段是[4,5]、均值4.5。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 14:24:05