在Pandas中将月度累计值转换为当月值(含缺失月份场景)
累计值转当月值的实现方案
针对你提到的缺失1月数据的数据集(df1)以及无缺失的数据集(df2),可以用Pandas的差分方法快速实现累计值转当月值,完全符合你的规则:
核心逻辑
- 确保时间顺序正确:累计值是按时间递增生成的,必须先把日期列转成datetime类型并排序,否则计算结果会出错。
- 计算当月值:用
diff()方法计算当前行累计值与上一行的差值,这就是当月值;对于最早的月份(不管是缺1月后的2月,还是正常的1月),因为没有上月数据,diff()会返回NaN,直接用该月的累计值填充即可。
代码示例
1. 处理缺失1月的df1
import pandas as pd # 构造示例df1(缺1月数据) df1 = pd.DataFrame({ 'date': ['2021-02-28', '2021-03-31', '2021-04-30'], 'cumul_val1': [12000.00, 36007.05, 50305.00], 'cumul_val2': [8000.00, 25000.00, 32000.00] }) # 转换日期格式并排序 df1['date'] = pd.to_datetime(df1['date']) df1 = df1.sort_values('date').reset_index(drop=True) # 计算当月值:差分后填充NaN为原累计值 df1['value1'] = df1['cumul_val1'].diff().fillna(df1['cumul_val1']) df1['value2'] = df1['cumul_val2'].diff().fillna(df1['cumul_val2']) # 保留需要的列(可选) df1 = df1[['date', 'value1', 'value2']] print(df1)
输出结果(符合预期):
date value1 value2 0 2021-02-28 12000.0 8000.0 1 2021-03-31 24007.05 17000.0 2 2021-04-30 14297.95 7000.0
2. 处理无缺失的df2
# 构造示例df2(含1月数据) df2 = pd.DataFrame({ 'date': ['2021-01-31', '2021-02-28', '2021-03-31', '2021-04-30'], 'cumul_val1': [10000.00, 22000.00, 46007.05, 60305.00], 'cumul_val2': [7000.00, 15000.00, 32000.00, 39000.00] }) df2['date'] = pd.to_datetime(df2['date']) df2 = df2.sort_values('date').reset_index(drop=True) df2['value1'] = df2['cumul_val1'].diff().fillna(df2['cumul_val1']) df2['value2'] = df2['cumul_val2'].diff().fillna(df2['cumul_val2']) df2 = df2[['date', 'value1', 'value2']] print(df2)
输出结果:
date value1 value2 0 2021-01-31 10000.0 7000.0 1 2021-02-28 12000.0 8000.0 2 2021-03-31 24007.05 17000.0 3 2021-04-30 14297.95 7000.0
3. 多分组场景(比如按ID分组)
如果数据是按不同主体(如用户ID、产品ID)分组的,每个分组有独立的累计值,只需加个groupby即可:
# 构造带分组的示例数据 df_group = pd.DataFrame({ 'id': ['A', 'A', 'A', 'B', 'B', 'B'], 'date': ['2021-02-28', '2021-03-31', '2021-04-30', '2021-01-31', '2021-02-28', '2021-03-31'], 'cumul_val1': [12000.00, 36007.05, 50305.00, 9000.00, 21000.00, 35000.00], 'cumul_val2': [8000.00, 25000.00, 32000.00, 6000.00, 14000.00, 22000.00] }) df_group['date'] = pd.to_datetime(df_group['date']) df_group = df_group.sort_values(['id', 'date']).reset_index(drop=True) # 按id分组计算当月值 df_group['value1'] = df_group.groupby('id')['cumul_val1'].diff().fillna(df_group['cumul_val1']) df_group['value2'] = df_group.groupby('id')['cumul_val2'].diff().fillna(df_group['cumul_val2']) print(df_group)
内容的提问来源于stack exchange,提问作者ah bon
相关产品推荐
相关产品推荐

