使用timedelta向datetime64添加一个月

时间:2019-02-20 20:05:41

标签: python pandas numpy timedelta

当我尝试这样做时:

get()

我希望看到

>>> a = numpy.datetime64('1995-12-31')
>>> b = a + pandas.Timedelta(1, unit='M')
>>> print(b)

但是我得到

1996-01-31

知道为什么吗?非常感谢。

5 个答案:

答案 0 :(得分:5)

正如他在回答中提到的@hpaulj:

在时间上加上“月”存在固有的歧义,因为月的长度各不相同。

此外,自版本0.25.0起,熊猫 dropped support用于单位M(月)和Y(年)的使用在Timedelta函数中。

但是,正如官方熊猫guide所述,对于绝对持续时间,应使用 Timedelta ,对于尊重日历算术的相对持续时间,应使用 DateOffset 正是您需要的情况:

基本的 DateOffset 的作用类似于dateutil.relativedeltarelativedelta documentation),它将日期时间偏移指定的相应日历持续时间。

因此,以您的示例为例:

In [7]: a = numpy.datetime64('1995-12-31')
      : b = pandas.Timestamp(a) + pandas.DateOffset(months=1)
      : b
Out[7]: Timestamp('1996-01-31 00:00:00')

注意:如果需要将to_numpy转换为pandas.Timestamp,则可以始终使用numpy.datetime64方法。

答案 1 :(得分:1)

一个月的时间增量是一年的长度除以12。

您需要检查日期并添加适当的天数。 或者,增加月份数(如果需要,可以滚动到下一年),并保持天数不变。

答案 2 :(得分:0)

您可以替换day部分以模仿要求。

import numpy as np
import pandas as pd
a = np.datetime64('1995-12-31')
b = a + pd.Timedelta(1, unit='M')
print(b.replace(day=pd.to_datetime(a).day))

如果您只对日期部分感兴趣,请使用.date()

答案 3 :(得分:0)

在时间中添加“月”存在固有的歧义,因为月的长度各不相同。

约会:

In [247]: a = np.array('1995-12-31','datetime64[D]')                            
In [248]: a                                                                     
Out[248]: array('1995-12-31', dtype='datetime64[D]')

向其中添加天数可以正常工作:

In [249]: a + np.array(31, 'timedelta64[D]')                                    
Out[249]: numpy.datetime64('1996-01-31')

加一个月会引发错误:

In [250]: a + np.array(1, 'timedelta64[M]')                                     
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-250-a331f724d7e7> in <module>
----> 1 a + np.array(1, 'timedelta64[M]')

TypeError: Cannot get a common metadata divisor for NumPy datetime metadata [D] and [M] because they have incompatible nonlinear base time units

我们可以将a投射为一个月-然后可以正常运行:

In [251]: a.astype('datetime64[M]')                                             
Out[251]: array('1995-12', dtype='datetime64[M]')
In [252]: a.astype('datetime64[M]') + np.array(1, 'timedelta64[M]')             
Out[252]: numpy.datetime64('1996-01')

在相应的datetime对象中更改月份可能是最干净的方法:

In [254]: b = a.item()                                                          
In [255]: b                                                                     
Out[255]: datetime.date(1995, 12, 31)

我还没有充分利用datetime对象来进行更改,而无需查看其文档。

答案 4 :(得分:0)

如果可能的话,添加一个月使日期保持不变的简洁方法是将其截断为几个月,再加上1,然后读取被截断的内容:

>>> a = np.datetime64('1995-12-31')                                                              
>>> am = a.astype('M8[M]')                                                    
>>> b = (am + 1) + (a - am)                                                        
>>> b                                                                                            
numpy.datetime64('1996-01-31')                                                                   

很明显,如果下个月不存在原始日期,则无法使用

>>> a = np.datetime64('1995-01-31')
>>> am = a.astype('M8[M]')
>>> b = (am + 1) + (a - am)
>>> b
numpy.datetime64('1995-03-03')

但是,无论如何,目前尚不清楚答案是什么。

一种可能性是在该月的最后一天达到上限:

>>> b = np.minimum((am + 1) + (a - am), (am + 2) - np.timedelta64(1, 'D'))
>>> b
numpy.datetime64('1995-02-28')