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

分组Pandas DataFrame计算月度百分比差异遇问题求助

问题:按ID分组计算月度百分比差异失败

我已经在按ID分组的DataFrame中算出了两个月度数值的差值,但使用.pct_change()方法计算百分比差异时,要么出现KeyError,要么结果全为NaN。

我的DataFrame结构如下:

IDMONTHTOTALVariance
REF11550
REF126510
REF13661
REF2765-15
REF268010
REF2810035

现有代码:

df_all = ( 
        pd.concat(pd.read_excel("testdata.xlsx",
                                header=None, sheet_name=None), ignore_index=True)
            .T.set_index(0).T
            .rename_axis(None, axis=1)
            .loc[:, ["ID", "DATE", "TOTAL"]]
            .assign(MONTH= lambda x: x["DATE"].dt.month)
            .groupby(by=["ID", "MONTH"], as_index=False).agg({"TOTAL":sum})
     )

df_all['Variance'] = df_all['TOTAL'].sub(
           df_all[['ID', 'MONTH']]
           .merge(df_all.assign(MONTH=df_all['MONTH'].add(1)),
                  how='left')['TOTAL']
          )
df_all['Variance'].fillna(0, inplace=True)

解决方法

问题根源在于:.pct_change()默认按整列顺序计算,但你的数据未按ID和MONTH排序,且未分组,导致跨ID计算或顺序错乱,出现错误/NaN。

方法一:分组+排序后用.pct_change()

这是最简洁的实现方式:

# 1. 先按ID和MONTH排序,确保每个ID下的月份递增
df_all = df_all.sort_values(by=['ID', 'MONTH'])

# 2. 按ID分组,计算每个ID内部的月度百分比变化
df_all['Pct_Change'] = df_all.groupby('ID')['TOTAL'].pct_change()

# 3. 处理第一个月的NaN(按需填充为0或保留)
df_all['Pct_Change'] = df_all['Pct_Change'].fillna(0)

# 可选:转成百分比格式(保留两位小数)
df_all['Pct_Change'] = df_all['Pct_Change'].apply(lambda x: f"{x*100:.2f}%")

方法二:沿用你的merge逻辑计算百分比

如果你想继续用merge方式实现:

import pandas as pd

# 1. 生成上月数据的临时表,重命名TOTAL列
df_prev_month = df_all.assign(MONTH=df_all['MONTH'] + 1).rename(columns={'TOTAL': 'Prev_Total'})

# 2. 合并到原表,匹配相同ID和上月的MONTH
df_all = df_all.merge(df_prev_month[['ID', 'MONTH', 'Prev_Total']], 
                      on=['ID', 'MONTH'], 
                      how='left')

# 3. 计算百分比差异,处理空值和除数为0的情况
df_all['Pct_Change'] = df_all.apply(
    lambda row: (row['TOTAL'] - row['Prev_Total']) / row['Prev_Total'] 
    if pd.notna(row['Prev_Total']) and row['Prev_Total'] != 0 
    else 0,
    axis=1
)

# 4. 移除临时列
df_all.drop('Prev_Total', axis=1, inplace=True)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 21:01:19