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

按CODE分组计算连续8个月NORMAL_PP累积值的问题排查

解决按CODE分组计算连续8个月累积值的NaN问题

问题背景

现有df_normales DataFrame,结构为6408行3列:

CODE         MONTH     NORMAL_PP
    0     000261      January      111.4
    ...
    6407  002412     December     236.7

需求是按CODE分组,计算NORMAL_PP的连续8个月累积值,要覆盖1月-8月、2月-9月……直到9月-次年4月的所有组合,最终输出格式要求包含两位月份编码的DATE_START、DATE_END。

原代码运行后出现大量NaN值,无法获取完整的连续累积结果。

原代码问题分析

原代码存在几个关键问题:

  • 字段名混淆:原始数据用MONTH列,但代码里错误使用DATE列,逻辑不匹配
  • 手动添加单行的方式无法覆盖所有跨年连续月份场景
  • rolling操作的方向反转导致末尾出现NaN,且未处理分组内数据的完整性
  • 存在拼写错误:assign里用了FECHA,但实际列名应为DATE
  • 使用append循环拼接DataFrame,效率低且易出错

修正后的解决方案

以下是完整的修正代码,逻辑清晰且能生成符合要求的结果:

import pandas as pd

# 第一步:给月份映射成数字编码,方便后续计算
month_map = {
    'January': '01', 'February': '02', 'March': '03',
    'April': '04', 'May': '05', 'June': '06',
    'July': '07', 'August': '08', 'September': '09',
    'October': '10', 'November': '11', 'December': '12'
}

# 转换MONTH为两位编码,同时转成数字方便计算
df_normales['MONTH_CODE'] = df_normales['MONTH'].map(month_map).astype(int)

# 初始化结果DataFrame
result = pd.DataFrame()

# 按CODE分组处理
for code, group in df_normales.groupby('CODE'):
    # 按月份编码排序,确保顺序正确
    group_sorted = group.sort_values('MONTH_CODE').reset_index(drop=True)
    
    # 拼接一份当前组的数据到末尾,处理跨年的连续8个月(比如9月到次年4月)
    # 拼接后的月份编码加12,模拟下一年的月份
    group_extended = pd.concat([
        group_sorted,
        group_sorted.assign(MONTH_CODE=lambda x: x['MONTH_CODE'] + 12)
    ]).reset_index(drop=True)
    
    # 计算连续8个月的累积值,min_periods=8确保只有8个完整数据才计算
    group_extended['CUMULATIVE_PP'] = group_extended['NORMAL_PP'].rolling(window=8, min_periods=8).sum()
    
    # 过滤出有效的起始行:前9个月份(对应1-9月作为起始,覆盖到次年4月)
    valid_rows = group_extended.iloc[:9].copy()
    
    # 计算DATE_END:起始月份+7,超过12的取模12,注意处理0的情况(12月+7=19→19%12=7→07)
    valid_rows['DATE_END_CODE'] = valid_rows['MONTH_CODE'].apply(lambda x: (x + 7) % 12)
    valid_rows['DATE_END_CODE'] = valid_rows['DATE_END_CODE'].replace(0, 12).astype(str).str.zfill(2)
    
    # 转DATE_START为两位编码
    valid_rows['DATE_START'] = valid_rows['MONTH_CODE'].astype(str).str.zfill(2)
    
    # 整理成目标格式
    valid_rows = valid_rows[['DATE_START', 'CUMULATIVE_PP', 'DATE_END_CODE', 'CODE']]
    valid_rows.columns = ['DATE_START', 'NORMAL_PP', 'DATE_END', 'CODE']
    
    # 合并到结果
    result = pd.concat([result, valid_rows], ignore_index=True)

# 查看结果
print(result.head())

代码说明

  1. 月份编码转换:把英文月份转成数字编码,方便后续的加减和排序
  2. 扩展分组数据:将每组数据拼接一份(月份编码+12),解决跨年连续8个月的计算问题
  3. 滚动累积计算:用rolling(8, min_periods=8)确保只有凑齐8个月份才计算,避免NaN
  4. 月份编码转换回两位格式:处理跨年的月份编码,比如12月+7个月是次年7月,转成07
  5. 结果整理:过滤出有效的起始行(共9组,对应1-9月起始),调整列名到目标格式

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 10:17:30