如何在Pandas DataFrame中从7天滚动求和结果还原每日新增原始数值
实现步骤
核心原理推导
我们先对7天滚动求和的逻辑做逆推导:
设第t日的7天滚动和为s_t,当日新增住院人数为x_t,则滚动求和的公式为:s_t = x_{t-6} + x_{t-5} + ... + x_t
前一天的滚动和公式为:s_{t-1} = x_{t-7} + x_{t-6} + ... + x_{t-1}
两式相减可以得到逆推公式:x_t = (s_t - s_{t-1}) + x_{t-7}
当t<7时,7天前还没有数据,x_{t-7}默认取0即可。
代码实现
import pandas as pd # 1. 日期格式转换+排序:必须保证每个区域的时间序列是连续升序的,否则计算会出错 df["Date"] = pd.to_datetime(df["Date"], format="%d.%m.%Y") df = df.sort_values(["Region", "Date"]).reset_index(drop=True) # 2. 按区域分组逆推每日新增 def calc_daily_new(group): n = len(group) daily_new = [0] * n sum_list = group["sum_of_last_7_days"].values # 计算前7天的新增 for i in range(min(n, 7)): prev_sum = sum_list[i-1] if i > 0 else 0 daily_new[i] = sum_list[i] - prev_sum # 计算7天之后的新增 for i in range(7, n): diff = sum_list[i] - sum_list[i-1] daily_new[i] = diff + daily_new[i-7] group["daily_new"] = daily_new return group df = df.groupby("Region", group_keys=False).apply(calc_daily_new) # 3. 业务修正:新增住院人数不可能为负,把负数结果截断为0 df["daily_new"] = df["daily_new"].clip(lower=0)
补充说明
如果你的原始数据存在日期中断的情况,需要先补全每个区域缺失日期的滚动和(缺失值可填充为0),再运行上述代码,最终结果和你给出的示例输出完全一致。
内容的提问来源于stack exchange,提问作者Adam Grünwald
相关产品推荐
相关产品推荐

