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

如何用Python实现DataFrame滚动求和并标记抵消组?

解决方案

原代码问题分析

你的代码存在以下关键问题,导致无法得到预期结果:

  • 仅标记了滚动窗口的最后一行,没有将窗口内的所有行标记为Canceled
  • 只处理了固定5行的窗口,未覆盖需求中的2-4行窗口
  • 缺少组编号和组内行号的生成逻辑

完整实现代码

以下是满足需求的完整代码,包含数据预处理、滚动窗口标记、组编号与行号生成:

# 1. 数据预处理(保留你的原有筛选逻辑)
df_sorted = df.sort_values('No Piece FI')
df_sorted['No Piece FI'] = df_sorted['No Piece FI'].astype(str)
df = df_sorted[df_sorted['No Piece FI'].str.startswith('11')].reset_index(drop=True)

# 2. 初始化标记列
df['Annulé'] = ''

# 3. 遍历2-5行的所有窗口大小,标记和为0的窗口内所有行
for window_size in range(2, 6):
    # 计算指定窗口大小的滚动和(min_periods=window_size确保窗口是满员的N行)
    rolling_sums = df['CP'].rolling(window=window_size, min_periods=window_size).sum()
    # 找到所有和为0的窗口的结束索引
    zero_window_end_indices = rolling_sums[rolling_sums == 0].index
    # 标记每个窗口内的全部行
    for end_idx in zero_window_end_indices:
        start_idx = end_idx - window_size + 1
        df.loc[start_idx:end_idx, 'Annulé'] = 'Canceled'

# 4. 生成组编号:连续的相同标记状态为一组
df['Group'] = (df['Annulé'] != df['Annulé'].shift()).cumsum()

# 5. 生成组内行号
df['Lines'] = df.groupby('Group').cumcount() + 1

# (可选)调整列顺序匹配预期输出
df = df[['Lines', 'CP', 'Annulé', 'Group']]

代码说明

  1. 重置索引:避免原DataFrame索引不连续导致窗口切片错误
  2. 多窗口遍历:依次处理2/3/4/5行的窗口,确保覆盖所有需求中的窗口大小
  3. 全窗口标记:找到和为0的窗口结束索引后,通过切片标记该窗口内的所有行
  4. 组编号生成:通过对比当前行与上一行的Annulé状态,将连续的相同状态划分为同一组
  5. 组内行号:用groupby.cumcount()生成每组内的递增行号

特殊情况调整

如果你的需求是「窗口最大5行,最少2行(即包含2-5行的任意滚动窗口)」,而非固定窗口大小,可以修改滚动求和逻辑:

window_max = 5
# 计算最大5行、最少2行的滚动和
rolling_sums = df['CP'].rolling(window=window_max, min_periods=2).sum()
# 标记所有和为0的窗口内的行
for idx in rolling_sums[rolling_sums == 0].index:
    start_idx = max(0, idx - window_max + 1)
    df.loc[start_idx:idx, 'Annulé'] = 'Canceled'

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 17:03:14