Pandas如何基于条件向日期列向量式添加对应时间增量
实现方案
原有代码的问题
你之前的写法有两个本质问题:
- Python标准库的
datetime.timedelta仅支持标量值传参,直接传入Series类型的tf_int必然报错 timedelta本身不支持月、年这类时长不固定的时间单位,就算解决了传参问题,也处理不了M、Y维度的偏移需求,更满足不了「月偏移保留原日字段」的规则。
向量化实现代码
不需要反复写.loc做条件判断,也不需要逐行循环,用pandas原生的DateOffset配合分组批量偏移即可,性能和简洁度都满足要求:
import pandas as pd # 第一步:先把Date列转为pandas标准datetime类型,所有时间操作的前置要求 df['Date'] = pd.to_datetime(df['Date']) # 时间单位和DateOffset参数的映射表,后续新增时间单位直接在字典里加键值对就行 unit_param_map = { 'D': 'days', 'W': 'weeks', 'M': 'months', 'Y': 'years' } # 初始化结果列 df['publish_date'] = pd.Series(dtype='datetime64[ns]', index=df.index) # 按时间单位分组做批量向量偏移,同单位的行一次性计算完成 for unit, param in unit_param_map.items(): row_mask = df['tf'] == unit df.loc[row_mask, 'publish_date'] = df.loc[row_mask, 'Date'] + pd.DateOffset( **{param: df.loc[row_mask, 'tf_int']} )
运行结果
针对给出的示例数据集,运行后输出完全符合预期:
| Date | tf | tf_int | publish_date |
|---|---|---|---|
| 2022-01-01 | D | 1 | 2022-01-02 |
| 2022-01-02 | W | 3 | 2022-01-23 |
| 2022-01-03 | M | 2 | 2022-03-03 |
| 2022-01-04 | Y | 2 | 2024-01-04 |
补充说明:这里用
pd.DateOffset的months/years参数做偏移时,会默认保留原日期的日字段,刚好匹配提出的月偏移规则。如果后续需要处理月末日期(比如1月31日加1个月自动对齐到月末),只需要把对应单位的Offset换成pd.offsets.MonthEnd/YearEnd即可。
性能提示
不要用df.apply(..., axis=1)的逐行写法,本质是Python层的逐行循环,数据量到10万行以上时速度会比上面的分组批量计算慢几十上百倍。上面的写法每个时间单位仅做一次向量运算,性能和pandas原生向量化操作一致。
内容的提问来源于stack exchange,提问作者Charizard_knows_to_code
相关产品推荐
相关产品推荐

