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

如何用Python按连续3天增减趋势为DataFrame分组?

连续3天趋势分组与分段斜率实现方案

直接上可运行的代码与逻辑拆解:

1. 准备数据与标记每日趋势

用diff()计算每日数值变化,生成趋势标记列:

import pandas as pd
import numpy as np
from sklearn.linear_model import LinearRegression

# 示例数据
df = pd.DataFrame({
    'date': pd.date_range('2022-09-01', periods=10),
    'value': [10, 8, 6, 7, 9, 12, 10, 8, 7, 9]
})

# 标记每日趋势:1=上升,-1=下降,0=持平
df['trend'] = df['value'].diff().map(lambda x: 1 if x > 0 else (-1 if x < 0 else 0))

2. 识别连续3天趋势并生成分组

核心思路是先找出连续相同趋势的"块",再筛选出长度≥3的块作为分组分界,最后统一分组编号:

# 标记连续相同趋势的块(每次趋势变化则块编号+1)
df['trend_block'] = (df['trend'] != df['trend'].shift()).cumsum()

# 计算每个块的长度
df['block_len'] = df.groupby('trend_block')['trend'].transform('count')

# 标记需要独立分组的块:长度≥3的上升/下降块
df['is_valid_group'] = (df['block_len'] >= 3) & (df['trend'] != 0)

# 生成最终分组编号:每个有效块对应唯一分组,无效块归为0
df['group'] = df['is_valid_group'].cumsum()
# 把同一趋势块内的行统一为该块的分组编号
df['group'] = df.groupby('trend_block')['group'].transform('max').fillna(0).astype(int)

3. 计算分段线性斜率

对每个分组用线性回归拟合斜率,将日期转换为距离分组起始日的天数作为自变量:

def get_segment_slope(group):
    # 将分组内的日期转为连续数值(第0天、第1天...)
    X = np.arange(len(group)).reshape(-1, 1)
    y = group['value'].values
    reg = LinearRegression(fit_intercept=True)
    reg.fit(X, y)
    return reg.coef_[0]

# 计算每个分组的斜率并合并回原表
slope_df = df.groupby('group').apply(get_segment_slope).reset_index(name='segment_slope')
df = df.merge(slope_df, on='group', how='left')

关键逻辑说明

  • 趋势块标记:通过trend != trend.shift()判断趋势是否变化,累积计数得到每个连续趋势的块ID
  • 有效分组筛选:只有长度≥3的上升/下降块才会触发新分组,持平块不会触发分组拆分
  • 斜率计算:用简单线性回归拟合每个分组内的数值变化,得到分段斜率

自定义调整点

  • 如果需要忽略持平(即把持平视为延续之前的趋势),可以先把trend中的0替换为前一个非0值:df['trend'] = df['trend'].replace(0, method='ffill')
  • 若希望未达到3天连续趋势的初始数据单独分组,可调整group的初始值逻辑

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 21:13:21