如何对含多升级日期列的Pandas DataFrame按月重采样生成月度状态表
解决方法
1. 核心实现逻辑
- 先将原始数据的升级日期统一转换为当月首日,方便后续比较
- 生成指定时间范围的月度序列,与所有key做笛卡尔积,得到每个key对应所有月份的全量行
- 逐行判断当前月份是否晚于升级日期的当月首日,是则标记为1,否则为0,NaT统一标记为0
2. 完整可运行代码
import pandas as pd # 构造原始数据 df = pd.DataFrame({ 'key': ['key1', 'key2'], 'date_upgrade1': pd.to_datetime(['2020-07-31', '2020-05-31']), 'date_upgrade2': pd.to_datetime(['2020-08-31', pd.NaT]) }) # 1. 预处理:将升级日期转成当月首日 df['upgrade1_month'] = df['date_upgrade1'].dt.to_period('M').dt.to_timestamp() df['upgrade2_month'] = df['date_upgrade2'].dt.to_period('M').dt.to_timestamp() # 2. 生成指定范围的月度序列(可根据需求调整start、end参数修改时间范围) month_range = pd.date_range(start='2020-06-01', end='2020-09-01', freq='MS').to_frame(name='month').reset_index(drop=True) # 3. 生成key与月份的全量组合 full_df = df[['key', 'upgrade1_month', 'upgrade2_month']].merge(month_range, how='cross') # 4. 计算upgrade取值 full_df['upgrade1'] = (full_df['month'] > full_df['upgrade1_month']).astype(int) full_df['upgrade2'] = (full_df['month'] > full_df['upgrade2_month']).astype(int) # 5. 筛选需要的列,按规则排序得到最终结果 result = full_df[['month', 'key', 'upgrade1', 'upgrade2']].sort_values(['key', 'month']).reset_index(drop=True) print(result)
3. 规则匹配说明
- 代码中
freq='MS'表示生成的时间序列为每月第一天,和示例输出的month字段格式完全一致 - 判断逻辑
month > 升级日期当月首日严格匹配需求:升级完成当月仍然标记为0,下一个月开始标记为1 - NaT参与比较时默认返回False,会自动标记为0,无需额外处理空值
内容的提问来源于stack exchange,提问作者Goliath
相关产品推荐
相关产品推荐

