使用Lambda与Apply计算日期月份差遇属性错误求助
计算日期月份差时的AttributeError问题解决
遇到的错误
AttributeError: 'datetime.date' object has no attribute 'dt'
你的日期转换代码
df['date1'] = pd.to_datetime(df['date1'], errors='ignore', infer_datetime_format=True) df['date2'] = pd.to_datetime(df['date2'], errors='ignore', infer_datetime_format=True)
两段尝试代码
df['Duration (Months)'] = df.apply(lambda x: x["Date1"].dt.to_period('M').astype(int) - x["Date2"].dt.to_period('M').astype(int), axis=1)
df['Duration (Months)'] = df['date1'].dt.to_period('M').astype(int) - df['date2'].dt.to_period('M').astype(int)
问题根源
errors='ignore'导致类型不统一pd.to_datetime加了errors='ignore'后,一旦遇到无法转换的日期格式,会直接保留原数据类型(比如Python原生的datetime.date对象),而只有pandas的datetime64类型Series才能用.dt访问器,原生datetime.date对象没有这个属性,所以报错。第一段代码的额外问题
列名大小写不匹配:你定义的列是date1/date2,但lambda里写的是Date1/Date2,会触发KeyError;同时apply(axis=1)时,x["date1"]是单个日期对象,不能用.dt访问器(.dt是给整个Series用的)。
修复方案
方案1:高效的Series级处理(推荐)
先修正日期转换逻辑,用errors='coerce'替代errors='ignore',转换失败的会变成NaT(方便后续处理),确保列是datetime64类型:
# 重新转换日期,确保类型统一 df['date1'] = pd.to_datetime(df['date1'], infer_datetime_format=True, errors='coerce') df['date2'] = pd.to_datetime(df['date2'], infer_datetime_format=True, errors='coerce') # 直接用Series的.dt访问器计算月份差 df['Duration (Months)'] = df['date1'].dt.to_period('M').astype(int) - df['date2'].dt.to_period('M').astype(int)
方案2:用apply的正确写法(不推荐,效率低)
如果一定要用apply,单个日期对象直接调用to_period方法,同时修正列名大小写:
df['date1'] = pd.to_datetime(df['date1'], infer_datetime_format=True, errors='coerce') df['date2'] = pd.to_datetime(df['date2'], infer_datetime_format=True, errors='coerce') df['Duration (Months)'] = df.apply(lambda x: x['date1'].to_period('M').astype(int) - x['date2'].to_period('M').astype(int), axis=1)
内容的提问来源于stack exchange,提问作者Mike Mann
相关产品推荐
相关产品推荐

