如何计算Pandas中含NaT的datetime列均值?解决两类报错问题
解决Pandas中Datetime列求均值的踩坑经历
最近我在处理一个带datetime类型的DataFrame时遇到了麻烦,先给大家看下我的数据代码:
import pandas as pd import datetime import numpy as np d = { 'DOB': pd.Series([ datetime.datetime(2014, 7, 9), datetime.datetime(2014, 7, 15), np.datetime64('NaT') ], index=['a', 'b', 'c']) } df_test = pd.DataFrame(d)
本来想直接调用df_test['DOB'].mean()求均值,结果直接报错:
TypeError: reduction operation 'mean' not allowed for this dtype
我跑去Stack Overflow找解决方案,结果运行里面的函数时又碰上新错误:
OverflowError: Python int too large to convert to C long
折腾了半天,终于找到几个可行的办法,能得到预期的datetime.datetime(2014, 7, 12)结果,分享给大家:
可行解决方案
方法一:转成numpy时间戳计算均值
这个思路是把有效日期转成numpy的int64类型时间戳,计算均值后再转回来,完美避开溢出问题:
# 先过滤掉NaT,转成int64时间戳求均值 timestamp_mean = df_test['DOB'].dropna().astype(np.int64).mean() # 转回到datetime类型 mean_date = pd.to_datetime(timestamp_mean) print(mean_date.to_pydatetime()) # 输出: datetime.datetime(2014, 7, 12, 0, 0)
方法二:用时间差计算均值
如果担心时间戳的大整数问题,还可以用基准日期+时间差均值的方式:
# 取第一个有效日期当基准 base_date = df_test['DOB'].dropna().iloc[0] # 计算所有日期和基准的时间差的均值 delta_mean = (df_test['DOB'].dropna() - base_date).mean() # 基准日期加上时间差均值就是结果 mean_date = base_date + delta_mean print(mean_date.to_pydatetime()) # 输出: datetime.datetime(2014, 7, 12, 0, 0)
方法三:升级Pandas直接调用mean(最简单)
如果你用的是Pandas 1.1.0及以上版本,其实datetime类型的Series已经支持直接调用mean()了,默认会跳过NaT值,简直省心:
mean_date = df_test['DOB'].mean() print(mean_date.to_pydatetime()) # 输出: datetime.datetime(2014, 7, 12, 0, 0)
要是你的Pandas版本太老,先升级一下:pip install --upgrade pandas
为啥之前的方案会溢出?
之前看到的旧方案很多是用Python原生的date.toordinal()把日期转成整数,一旦日期跨度很大,这个整数就会超出C long的范围,直接触发溢出错误。而上面的方法要么用numpy的int64(支持更大数值范围),要么用时间差计算,都绕开了这个坑。
内容的提问来源于stack exchange,提问作者Nick
相关产品推荐
相关产品推荐

