You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何计算DataFrame中两日期列的已完成月份差值?

嘿,这个问题我熟!你遇到的报错是因为relativedelta本身是用来处理单个日期对象的,直接丢给Pandas Series肯定会出问题——它没办法判断整个Series的布尔真值,所以才抛出了那个模糊错误。

咱们一步步来解决这个计算已完成月份差的需求:

第一步:先把字符串日期转成Pandas datetime类型

你的原始数据里,dob是月/日/年格式,paymentDate是年月日数字串,得先把它们转换成Pandas能识别的日期类型,同时处理空值:

import pandas as pd
from dateutil import relativedelta

# 先构造你的示例数据
data = {'dob': {0: pd.NA, 1: '10/16/1988', 2: pd.NA, 3: pd.NA, 4: pd.NA}, 
        'paymentDate': {0: '20120501', 1: '20100602', 2: '20110601', 3: '20120501', 4: '20110101'}}
df = pd.DataFrame(data)

# 转换日期列,指定格式避免解析错误
df['dob'] = pd.to_datetime(df['dob'], format='%m/%d/%Y', errors='coerce')
df['paymentDate'] = pd.to_datetime(df['paymentDate'], format='%Y%m%d', errors='coerce')

第二步:计算已完成的月份差

这里有两种方法,选哪种看你的数据量:

方法1:自定义函数+apply(直观,适合小数据集)

我们写一个函数,逐行处理日期对,用relativedelta计算年和月的差,再根据日期的日部分判断是否要减去1个月(比如付款日早于出生日期的日,说明当月还没走完,不算完整月份):

def get_full_months(row):
    dob = row['dob']
    pay_date = row['paymentDate']
    # 只要有一个日期是空的,就返回空值
    if pd.isna(dob) or pd.isna(pay_date):
        return pd.NA
    delta = relativedelta.relativedelta(pay_date, dob)
    total_months = delta.years * 12 + delta.months
    # 如果付款日的日数小于出生日期的日数,说明当月还没完成,减1
    if pay_date.day < dob.day:
        total_months -= 1
    return total_months

# 应用到每一行
df['difference_in_months'] = df.apply(get_full_months, axis=1)

方法2:矢量化计算(高效,适合大数据集)

如果你的数据量很大,apply效率会偏低,用Pandas的矢量化操作更快:

# 计算年差和月差
year_diff = df['paymentDate'].dt.year - df['dob'].dt.year
month_diff = df['paymentDate'].dt.month - df['dob'].dt.month
# 检查日部分:付款日 < 出生日期的日,标记为1(需要减1个月)
day_adjustment = (df['paymentDate'].dt.day < df['dob'].dt.day).astype(int)
# 计算总月份差
df['difference_in_months'] = year_diff * 12 + month_diff - day_adjustment
# 把有缺失值的行重置为NaN
df['difference_in_months'] = df['difference_in_months'].where(df['dob'].notna() & df['paymentDate'].notna(), pd.NA)

验证结果

运行完上面的代码后,你会得到预期的结果:

dob paymentDate  difference_in_months
0  NaT  2012-05-01                    NaN
1 1988-10-16 2010-06-02                  259
2  NaT  2011-06-01                    NaN
3  NaT  2012-05-01                    NaN
4  NaT  2011-01-01                    NaN

完全符合你要的第二行结果259~

内容的提问来源于stack exchange,提问作者Nick

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 09:18:08