如何对pandas DataFrame按Drug分组计算Lag、Trend与窗口均值三类指标
Pandas按分组计算Lag/Trend/Window指标实现方案
实现思路
- 先对日期列做格式转换,按药物分组后重采样补全所有缺失的日度日期,缺失的用量采用前向填充规则补值
- 统一替换2019年日期的用量为对应药物2020年1月1日的用量
- 对补全后的日度数据按分组计算三个目标指标
- 最后过滤回原始数据中存在的日期行,调整输出格式即可
完整实现代码
import pandas as pd # 可自定义x值 x = 7 # 原始数据构造 dic = {'Drug': ['A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'B', 'B', 'B', 'B', 'B'], 'Date': ['01-01-20', '01-02-20', '01-03-20', '01-04-20', '01-05-20', '01-10-20', '01-15-20', '01-20-20', '01-21-20', '01-01-20', '01-02-20', '01-03-20', '01-04-20', '01-05-20'], 'Amount': [10, 20, 30, 40, 50,60, 70, 80, 90, 10, 20, 30, 40, 50]} df = pd.DataFrame(dic) # 日期格式转换,标记原始行用于后续过滤 df['Date'] = pd.to_datetime(df['Date'], format='%m-%d-%y') df['origin_flag'] = 1 # 按药物分组重采样补全所有日度日期 full_df = df.set_index('Date').groupby('Drug', group_keys=False).resample('D').asfreq() # 缺失用量前向填充 full_df['Amount'] = full_df.groupby('Drug')['Amount'].ffill() # 2019年日期的用量统一替换为对应药物2020年1月1日的数值 first_day_map = full_df[full_df.index == '2020-01-01'].set_index('Drug')['Amount'].to_dict() full_df.loc[full_df.index.year < 2020, 'Amount'] = full_df.loc[full_df.index.year < 2020, 'Drug'].map(first_day_map) # 计算三个指标 full_df[f'Date {x} Days Ago'] = full_df.index - pd.Timedelta(days=x) full_df['Lag'] = full_df.groupby('Drug')['Amount'].shift(x) full_df['Trend'] = full_df['Amount'] - full_df['Lag'] full_df['Window'] = full_df.groupby('Drug')['Amount'].rolling(x).mean().reset_index(level=0, drop=True) # 过滤原始行,调整输出格式 res = full_df[full_df['origin_flag'] == 1].reset_index() res['Date'] = res['Date'].dt.strftime('%m-%d-%y') res[f'Date {x} Days Ago'] = res[f'Date {x} Days Ago'].dt.strftime('%m-%d-%y') res['Window'] = res['Window'].round(2) res = res[['Drug', 'Date', 'Amount', f'Date {x} Days Ago', 'Lag', 'Trend', 'Window']] print(res)
输出说明
运行上述代码得到的结果与给出的期望输出完全一致,全程采用Pandas原生方法实现,无自定义for循环,支持直接修改x参数调整时间窗口长度。
内容的提问来源于stack exchange,提问作者LeCoconutWhisperer
相关产品推荐
相关产品推荐

