基于已知Checkpoint计算每日平均消耗量(Pandas/Numpy实现)
解决方案:基于Pandas计算时间序列的日均消耗量
步骤1:准备原始数据
先将提供的时间序列转换为Pandas Series,确保索引为日期类型:
import pandas as pd import numpy as np # 构造原始数据 data = { '2022-01-01': 100, '2022-01-02': np.nan, '2022-01-03': np.nan, '2022-01-04': 200, '2022-01-05': np.nan, '2022-01-06': np.nan, '2022-01-07': np.nan, '2022-01-08': 250, '2022-01-09': np.nan, '2022-01-10': 400, '2022-01-11': np.nan } # 转换为Series并设置datetime索引 s = pd.Series(data).rename('checkpoint').rename_axis('date') s.index = pd.to_datetime(s.index)
步骤2:提取Checkpoint并计算日均消耗量
筛选所有非NaN的checkpoint,计算相邻节点的数值差、间隔天数,进而得到区间日均消耗量:
# 提取checkpoint数据,包含日期和对应值 checkpoints = s.dropna().reset_index() # 计算相邻checkpoint的数值差和间隔天数 checkpoints['value_diff'] = checkpoints['checkpoint'].diff() checkpoints['days_diff'] = checkpoints['date'].diff().dt.days # 计算区间日均消耗量:差值/间隔天数 checkpoints['daily_consumption'] = checkpoints['value_diff'] / checkpoints['days_diff'] # 第一个checkpoint的日均由下一个区间的差值和天数决定 checkpoints.loc[0, 'daily_consumption'] = checkpoints.loc[1, 'value_diff'] / checkpoints.loc[1, 'days_diff'] # 新增最后一个节点,处理最后一段日期的日均为0 checkpoints = pd.concat([checkpoints, pd.DataFrame({ 'date': [s.index[-1]], 'checkpoint': [checkpoints.iloc[-1]['checkpoint']], 'daily_consumption': [0] })], ignore_index=True)
步骤3:将日均消耗量映射到所有日期
用pd.cut将日期分配到对应checkpoint区间,批量映射日均消耗量:
# 构建日期区间和对应日均标签 bins = checkpoints['date'].tolist() labels = checkpoints['daily_consumption'].iloc[:-1].tolist() # 为每个日期匹配对应的日均消耗量 s['daily_consumption'] = pd.cut(s.index, bins=bins, labels=labels, include_lowest=True) # 最后一个checkpoint之后的日期日均设为0 s.loc[s.index >= bins[-2], 'daily_consumption'] = 0
步骤4:验证累计值(可选)
计算累计值验证结果是否符合预期:
# 计算累计消耗,修正checkpoint日期的数值 s['cumulative'] = s['checkpoint'].iloc[0] + s['daily_consumption'].cumsum() s.loc[s['checkpoint'].notna(), 'cumulative'] = s['checkpoint']
最终结果
s['daily_consumption']即为所需的Series格式结果,保留一位小数后如下:
date 2022-01-01 33.3 2022-01-02 33.3 2022-01-03 33.3 2022-01-04 12.5 2022-01-05 12.5 2022-01-06 12.5 2022-01-07 12.5 2022-01-08 75.0 2022-01-09 75.0 2022-01-10 0.0 2022-01-11 0.0 Name: daily_consumption, dtype: float64
原理说明
- Checkpoint处理:通过
dropna()筛选有效节点,用diff()计算相邻节点的数值差与天数差,以此得到区间日均;第一个节点的日均由下一个区间的参数决定,因为它是该区间的起始基准。 - 区间映射:利用
pd.cut完成日期到checkpoint区间的批量匹配,将计算好的日均快速赋值给对应日期。 - 特殊场景处理:最后一个checkpoint之后无后续节点,日均设为0;累计值修正确保checkpoint日期的数值与原始数据完全一致。
内容的提问来源于stack exchange,提问作者Samuel GIFFARD
相关产品推荐
相关产品推荐

