如何将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
相关产品推荐
相关产品推荐

