如何生成日期区间内YYYYMM格式新列并按范围赋值
问题描述
原始数据表格:
| ID | Name | StartDate | EndDate |
|---|---|---|---|
| 1 | Aa | 2021-10-14 | 2021-12-22 |
| 2 | Ab | 2021-12-02 | 2022-10-05 |
需求:添加所有介于min(StartDate)与max(EndDate)之间的YYYYMM格式新列,若该行的StartDate与EndDate包含该月份,则对应单元格赋值1,否则赋值0。示例输出如下:
| ID | Name | StartDate | EndDate | 202110 | 202111 | 202112 | 202201 | 202202 | 202203 | 202204 | 202205 | 202206 | 202207 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 1 | Aa | 2021-10-14 | 2021-12-22 | 1 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| 2 | Ab | 2021-12-02 | 2022-07-05 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
解决方案(Python Pandas实现)
步骤1:导入库并处理原始数据
先把日期列转换为datetime类型,方便后续月份维度的比较:
import pandas as pd # 构造原始数据 data = { 'ID': [1, 2], 'Name': ['Aa', 'Ab'], 'StartDate': ['2021-10-14', '2021-12-02'], 'EndDate': ['2021-12-22', '2022-10-05'] } df = pd.DataFrame(data) # 转换日期列格式为datetime df['StartDate'] = pd.to_datetime(df['StartDate']) df['EndDate'] = pd.to_datetime(df['EndDate'])
步骤2:生成目标月份列表
计算出需要覆盖的所有月份范围,转为YYYYMM格式的字符串:
# 获取首尾月份的周期对象(按月份维度) min_month = df['StartDate'].min().to_period('M') max_month = df['EndDate'].max().to_period('M') # 生成中间所有月份,格式化为YYYYMM字符串 target_months = pd.period_range(min_month, max_month, freq='M').strftime('%Y%m')
步骤3:批量生成月份列并赋值
遍历每个目标月份,判断每行的起止日期是否包含该月份,批量赋值1或0:
# 先提取每行的起止月份周期,避免重复计算 df['start_month'] = df['StartDate'].dt.to_period('M') df['end_month'] = df['EndDate'].dt.to_period('M') for month_str in target_months: current_month = pd.Period(month_str, freq='M') # 用向量化判断代替apply,处理大数据量时效率更高 df[month_str] = ((df['start_month'] <= current_month) & (current_month <= df['end_month'])).astype(int) # 删除临时生成的起止月份列 df = df.drop(['start_month', 'end_month'], axis=1)
查看最终结果
运行上述代码后,df即为符合要求的表格,打印输出即可:
print(df)
关键逻辑说明
核心判断逻辑是:当前月份是否在该行的起始月份和结束月份之间(包含两端),用周期对象(Period)做比较可以直接按月份维度判断,无需处理具体日期的细节。
内容的提问来源于stack exchange,提问作者nep
相关产品推荐
相关产品推荐

