将日期列转换为相对于起始日期的天数差

本文介绍如何使用 pandas 将日期列快速转换为以首个(或最小)日期为基准的“天数差”列,适用于时间序列分析、特征工程等场景,核心方法是利用 `sub()` 和 `dt.days` 实现高效计算。

在数据分析中,常需将原始日期列标准化为相对天数(例如“距首日第几天”),便于建模或可视化。给定一个由年、月、日三列构成的 DataFrame,首先需将其合并为标准 datetime64 类型,再计算与参考日期的时间差。

以下为完整实现步骤:

  1. 构造并转换日期列:使用 pd.to_datetime(df) 自动解析年/月/日三列,返回 Series;再通过 .to_frame('Date') 转为单列 DataFrame;
  2. 计算天数差:对 Date 列调用 .sub() 方法减去参考日期(如首行 iloc[0] 或全局最小值 min()),结果为 timedelta64[ns] 类型;
  3. 提取整数天数:使用 .dt.days 属性获取精确的天数(忽略小时、分钟等),生成整型 Days_from_start 列。
import pandas as pd

df = pd.DataFrame({
    'year': [2015, 2015, 2015],
    'month': [2, 2, 2],
    'day': [4, 5, 10]
})

# 构建日期列并计算相对天数(以首行为基准)
out = pd.to_datetime(df).to_frame('Date')
out['Days_from_start'] = out['Date'].sub(out['Date'].iloc[0]).dt.days

print(out)

输出:

        Date  Days_from_start
0 2015-02-04                0
1 2015-02-05                1
2 2015-02-10                6

⚠️ 注意事项:

  • 若数据含缺失值(NaT),.sub() 和 .dt.days 会自动返回 NaN,建议提前用 dropna() 或 fillna() 处理;
  • 使用 out['Date'].min() 可确保以最早日期为基准(适用于乱序数据);
  • .dt.days 返回的是完整日历天数(非工作日),若需排除周末/节假日,应改用 pd.bdate_range 或 np.busday_count 配合自定义逻辑。

该方法简洁、向量化、性能优异,是 pandas 时间特征工程中的标准实践。