datetime64、pd.DateOffset与unique()运算冲突问题求助
Pandas datetime64[ns] 数据使用unique()后加法报错的原因与解决
问题重现
现有一列datetime64[ns]类型的Pandas Series数据df.date_month:
df.date_month # 输出: # 0 2018-09-01 # 1 2018-09-01 # 2 2018-09-01 # 3 2018-09-01 # 4 2018-09-01 # ... # Name: date_month, Length: 4839993, dtype: datetime64[ns]
直接遍历前10条数据执行加法操作正常:
for i in df.date_month[0:10]: print(i + pd.DateOffset(months=12)) # 输出: # 2019-09-01 00:00:00 # 2019-09-01 00:00:00 # 2019-09-01 00:00:00 # 2019-09-01 00:00:00
但使用unique()获取唯一值后循环加法报错:
for i in df.date_month.unique(): print(i + pd.DateOffset(months=12)) # 报错: # UFuncTypeError Traceback (most recent call last) # <command-3708796390803054> in <module> # 1 for i in df.date_month.unique(): # ----> 2 print(i + pd.DateOffset(months=12)) # # UFuncTypeError: ufunc 'add' cannot use operands with types dtype('<M8[ns]') and dtype('O')
df.date_month.unique()的输出:
df.date_month.unique() # 输出: # array(['2018-09-01T00:00:00.000000000', '2018-04-01T00:00:00.000000000', # '2018-12-01T00:00:00.000000000', '2018-11-01T00:00:00.000000000', # '2018-07-01T00:00:00.000000000', '2018-05-01T00:00:00.000000000', # '2018-06-01T00:00:00.000000000', '2018-10-01T00:00:00.000000000', # '2018-08-01T00:00:00.000000000'], dtype='datetime64[ns]')
报错原因
- 直接遍历Pandas Series时,每个元素是Pandas Timestamp对象,该类型原生支持与
pd.DateOffset的加法运算。 unique()方法返回的是Numpy datetime64[ns]类型数组,数组内的元素是Numpy原生的datetime64类型,而非Pandas Timestamp。Numpy的datetime64类型无法直接与pd.DateOffset(Python object类型)执行加法操作,因此触发类型不兼容的UFuncTypeError。
解决方法
方法1:将unique结果转为Pandas DatetimeIndex
把Numpy数组转为Pandas的DatetimeIndex,元素会变回Timestamp:
for i in pd.DatetimeIndex(df.date_month.unique()): print(i + pd.DateOffset(months=12))
方法2:用drop_duplicates()替代unique()
drop_duplicates()返回的仍是Pandas Series,元素保持Timestamp类型:
for i in df.date_month.drop_duplicates(): print(i + pd.DateOffset(months=12))
方法3:使用Numpy timedelta替代DateOffset(注意局限性)
如果不需要处理复杂的日期偏移逻辑,可使用Numpy的timedelta64类型执行加法,但要注意Numpy的月份偏移是近似值(因为不同月份天数不同):
import numpy as np for i in df.date_month.unique(): print(i + np.timedelta64(12, 'M'))
内容的提问来源于stack exchange,提问作者Henri
相关产品推荐
相关产品推荐

