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

如何将Pandas中年度重置的累计和DataFrame还原为原始月度数据

还原按年重置的累计和数据为原始月度数据

现有DataFrame df1 存储的是按年重置的累计和值,需要将其还原为无累计计算的原始月度数据(即目标DataFrame df2),本质是反转groupby+cumsum的处理逻辑。

示例数据

累计和数据 df1

values  values1 values2
date            
2010-01-01  1   1   4
2010-02-01  3   2   8
2010-03-01  3   3   10
2010-04-01  5   4   13
2010-05-01  9   5   14
2010-06-01  12  5   15
2010-07-01  15  7   17
2010-08-01  16  11  18
2010-09-01  16  13  20
2010-10-01  18  13  20
2010-11-01  22  13  21
2010-12-01  26  15  21
2011-01-01  2   0   0
2011-02-01  5   2   4
2011-03-01  6   4   4
2011-04-01  6   6   6
2011-05-01  10  10  8
2011-06-01  13  10  9
2011-07-01  14  13  9
2011-08-01  15  16  11
2011-09-01  17  19  13
2011-10-01  17  19  16
2011-11-01  20  22  16
2011-12-01  22  23  19

目标原始月度数据 df2

test    test1   test2
date            
2010-01-01  1   1   4
2010-02-01  2   1   4
2010-03-01  0   1   2
2010-04-01  2   1   3
2010-05-01  4   1   1
2010-06-01  3   0   1
2010-07-01  3   2   2
2010-08-01  1   4   1
2010-09-01  0   2   2
2010-10-01  2   0   0
2010-11-01  4   0   1
2010-12-01  4   2   0
2011-01-01  2   0   0
2011-02-01  3   2   4
2011-03-01  1   2   0
2011-04-01  0   2   2
2011-05-01  4   4   2
2011-06-01  3   0   1
2011-07-01  1   3   0
2011-08-01  1   3   2
2011-09-01  2   3   2
2011-10-01  0   0   3
2011-11-01  3   3   0
2011-12-01  2   1   3

示例数据生成代码

以下是生成上述df1和df2的代码,用于理解原始累计逻辑:

import pandas as pd
import numpy as np

# 生成月度日期序列
date_range = pd.date_range(start='2010', end='2012', freq='M')
ndays = len(date_range)

# 生成原始月度数据
test_df = pd.DataFrame(
    {
        'date': date_range.strftime('%Y-%m'), 
        'test': np.random.randint(5, size=ndays),
        'test1': np.random.randint(5, size=ndays),
        'test2': np.random.randint(5, size=ndays)
    }
)

# 设置日期索引
test_df = test_df.set_index('date')
test_df.index = pd.to_datetime(test_df.index)

# 按年计算累计和,生成df1的数据源
test_df[['values','values1','values2']] = test_df.groupby(test_df.index.year)[['test','test1','test2']].cumsum()

# 拆分得到df1和df2
df1 = test_df[['values','values1','values2']].copy()
df2 = test_df[['test','test1','test2']].copy()

还原方法

核心逻辑是按年份分组后计算组内差分,因为累计和的逆操作就是求相邻月份的差值,而每年第一个月的累计值就是当月原始值(无前置数据)。

还原代码

import pandas as pd

# 假设df1已加载完成,索引为日期类型
# 按年份分组,计算组内差分,填充首月原始值
df2 = df1.groupby(df1.index.year).diff().fillna(df1)

# 重命名列名以匹配目标格式(可选)
df2.columns = ['test', 'test1', 'test2']

代码说明

  • groupby(df1.index.year):确保每年的数据独立计算,不会跨年度差分
  • .diff():计算当前行与上一行的差值,得到当月的原始增量
  • .fillna(df1):每组第一行没有上一行数据,直接用原累计值填充(即当月原始值)
  • 列名重命名:根据需求将values*改为test*,和目标df2对齐

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 08:00:30