Python:如何根据条件为DataFrame列填充日期值?
问题
现有如下Pandas DataFrame:
| event_name | start_date | end_date |
|---|---|---|
| Start | 2010-11-12 | 2015-01-05 |
| Phase 1 | 2015-01-05 | 2015-03-16 |
| Phase 2 | 2015-04-04 | 2018-03-11 |
| Phase 3 | 2018-03-11 | 2030-05-15 |
| Phase 4 | 2030-05-15 | 2035-01-01 |
| Phase 5 | 2035-01-01 | 2035-04-01 |
| Checkpoint | 2025-12-25 | NaT |
需要将其处理为:
| event_name | start_date | end_date |
|---|---|---|
| Start | 2010-11-12 | 2015-01-05 |
| Phase 1 | 2015-01-05 | 2015-03-16 |
| Phase 2 | 2015-04-04 | 2018-03-11 |
| Phase 3 | 2018-03-11 | 2030-05-15 |
| Phase 4 | 2030-05-15 | 2035-01-01 |
| Phase 5 | 2035-01-01 | 2035-04-01 |
| Checkpoint | 2025-12-25 | 2030-05-15 |
逻辑规则
- 'Checkpoint'的
end_date优先设置为'Phase 4'的start_date - 若'Phase 4'不存在,使用'Phase 5'的
start_date - 若两者都不存在,设置为'Checkpoint'自身
start_date往后推30天
尝试过的代码(注:存在拼写错误,evet_name应为event_name):
d_end = df.loc[(df['evet_name']== "Phase 4") | (df['event_name']== "Phase 5"), ['event_name','start_date']] d_end = pd.DataFrame(d_end) print("Printing d_end test {}".format((d_end)))
解决方案
核心思路
按优先级依次获取目标日期:先找'Phase 4'的start_date,找不到再找'Phase 5'的,最后计算30天后的日期,再赋值给'Checkpoint'的end_date。
完整实现代码
import pandas as pd # 构造初始DataFrame(如果是从外部读取可忽略此部分) data = { 'event_name': ['Start', 'Phase 1', 'Phase 2', 'Phase 3', 'Phase 4', 'Phase 5', 'Checkpoint'], 'start_date': ['2010-11-12', '2015-01-05', '2015-04-04', '2018-03-11', '2030-05-15', '2035-01-01', '2025-12-25'], 'end_date': ['2015-01-05', '2015-03-16', '2018-03-11', '2030-05-15', '2035-01-01', '2035-04-01', pd.NaT] } df = pd.DataFrame(data) # 转换为日期类型(确保日期运算正常) df['start_date'] = pd.to_datetime(df['start_date']) df['end_date'] = pd.to_datetime(df['end_date']) # 步骤1:按优先级获取目标日期 target_date = df.loc[df['event_name'] == 'Phase 4', 'start_date'].values # 若Phase4不存在,尝试Phase5 if len(target_date) == 0: target_date = df.loc[df['event_name'] == 'Phase 5', 'start_date'].values # 若两者都不存在,计算30天后的日期 if len(target_date) == 0: checkpoint_start = df.loc[df['event_name'] == 'Checkpoint', 'start_date'].iloc[0] target_date = checkpoint_start + pd.Timedelta(days=30) else: # 提取唯一日期值(假设event_name唯一) target_date = target_date[0] # 步骤2:给Checkpoint的end_date赋值 df.loc[df['event_name'] == 'Checkpoint', 'end_date'] = target_date # 输出结果 print(df)
代码说明
- 日期类型转换:先将
start_date和end_date转为datetime类型,避免字符串运算错误。 - 优先级判断:用
values获取结果数组,通过数组长度判断是否存在对应事件行,避免抛出KeyError。 - 边界处理:当'Phase 4'和'Phase 5'都不存在时,使用
pd.Timedelta计算30天后的日期,保证日期类型一致性。 - 赋值操作:直接用
loc定位到'Checkpoint'行,精准修改end_date字段。
内容的提问来源于stack exchange,提问作者kopitb
相关产品推荐
相关产品推荐

