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

更新包后np.timedelta64 'M'单位不支持,如何计算日期月差?

计算日期间月份差的替代方案(适配Pandas 2.1.4+、Numpy 1.26.2+)

问题背景

之前通过(df['to_date']-df['from_date'])/np.timedelta64(1, 'M')计算日期月份差的方式,在升级Pandas到2.1.4、Numpy到1.26.2后触发报错:

ValueError: Unit M is not supported. Only unambiguous timedelta values durations are supported. Allowed units are 'W', 'D', 'h', 'm', 's', 'ms', 'us', 'ns'

这是因为Numpy不再支持模糊时间单位(比如月份,不同月份天数不同)的直接转换。

解决方案

推荐三种可靠的计算方式:

方法1:整数月份差(精确)

通过年份差乘以12加上月份差,得到精确的整数月份数:

import pandas as pd
import numpy as np

df = pd.DataFrame({'from_date': ['01-10-2003', '15-12-2004', '01-08-2012', '09-07-2001'],
                  'to_date': ['01-11-2003', '15-12-2006', '01-09-2012', '09-12-2001']})
df['from_date'] = pd.to_datetime(df['from_date'], format='%d-%m-%Y')
df['to_date'] = pd.to_datetime(df['to_date'], format='%d-%m-%Y')

# 计算整数月份差
df['Months'] = (df['to_date'].dt.year - df['from_date'].dt.year) * 12 + (df['to_date'].dt.month - df['from_date'].dt.month)
df

适合需要精确整数月份的场景,比如两个日期同月同日时,结果就是完整的月份数。

方法2:Period对象相减(简洁)

将日期转换为月度周期(Period)后直接相减,得到整数月份差:

import pandas as pd
import numpy as np

df = pd.DataFrame({'from_date': ['01-10-2003', '15-12-2004', '01-08-2012', '09-07-2001'],
                  'to_date': ['01-11-2003', '15-12-2006', '01-09-2012', '09-12-2001']})
df['from_date'] = pd.to_datetime(df['from_date'], format='%d-%m-%Y')
df['to_date'] = pd.to_datetime(df['to_date'], format='%d-%m-%Y')

# 转换为月度Period后计算差值
df['Months'] = df['to_date'].dt.to_period('M') - df['from_date'].dt.to_period('M')
# 若需要转为数值类型,添加:
# df['Months'] = df['Months'].dt.n
df

结果默认是Period对象,添加dt.n可转为整数。

方法3:近似小数月份(兼容旧逻辑)

如果需要类似之前的小数月份结果(考虑当月天数比例),可手动计算:

import pandas as pd
import numpy as np

df = pd.DataFrame({'from_date': ['01-10-2003', '15-12-2004', '01-08-2012', '09-07-2001'],
                  'to_date': ['01-11-2003', '15-12-2006', '01-09-2012', '09-12-2001']})
df['from_date'] = pd.to_datetime(df['from_date'], format='%d-%m-%Y')
df['to_date'] = pd.to_datetime(df['to_date'], format='%d-%m-%Y')

# 总天数除以公历平均月天数(30.4375)
df['Months'] = (df['to_date'] - df['from_date']).dt.days / 30.4375
df

这种方式是近似值,适合不需要绝对精确的场景。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 21:53:12