Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/visual-studio-2008/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 熊猫日期范围-减去numpy timedelta得到奇数结果,时间变为非0:00:00_Python_Pandas_Numpy_Datetime_Timedelta - Fatal编程技术网

Python 熊猫日期范围-减去numpy timedelta得到奇数结果,时间变为非0:00:00

Python 熊猫日期范围-减去numpy timedelta得到奇数结果,时间变为非0:00:00,python,pandas,numpy,datetime,timedelta,Python,Pandas,Numpy,Datetime,Timedelta,我正在尝试使用pandas date_range功能生成一组日期。然后我想迭代这个范围,从每个日期中减去几个月(确切的月数在循环中确定),以获得一个新的日期 当我这样做的时候,我得到了一些非常奇怪的结果 MVP: 到目前为止还不错 现在让我们假设我只想从这个日期起一个月后回去。我定义numpy timedelta(它支持月的定义,而pandas的timedelta不支持): 为什么会这样?为什么我的时间是13:30:54而不是午夜 此外,如果我减去超过1个月的时间,则偏移量会变得非常大,以至于我

我正在尝试使用pandas date_range功能生成一组日期。然后我想迭代这个范围,从每个日期中减去几个月(确切的月数在循环中确定),以获得一个新的日期

当我这样做的时候,我得到了一些非常奇怪的结果

MVP:

到目前为止还不错

现在让我们假设我只想从这个日期起一个月后回去。我定义numpy timedelta(它支持月的定义,而pandas的timedelta不支持):

为什么会这样?为什么我的时间是13:30:54而不是午夜

此外,如果我减去超过1个月的时间,则偏移量会变得非常大,以至于我损失了整整一天:

#let's say I want to subtract both 2 years and then 1 month
deltaTrain = np.timedelta64(2,'Y')
#subtract 2 years and then subtract 1 month 
date - deltaTrain - deltaGap
Timestamp('2010-12-02 01:52:30', freq='3MS')

我在
timedelta
方面也遇到过类似的问题,我最终使用的解决方案是使用
dateutil
中的
relativedelta
,它是专门为此类应用程序构建的(考虑到闰年、工作日等所有日历奇怪之处)。例如:

from dateutil.relativedelta import relativedelta

date = dates[0]

>>> date
Timestamp('2013-01-01 00:00:00', freq='10MS')

deltaGap = relativedelta(months=1)

>>> date-deltaGap
Timestamp('2012-12-01 00:00:00', freq='10MS')

deltaGap = relativedelta(years=2, months=1)

>>> date-deltaGap
Timestamp('2010-12-01 00:00:00', freq='10MS')
有关
relativedelta

numpy.timedelta64的问题

我认为
np.timedelta
的问题在以下两个部分中有所揭示:

有两个时间增量单位(“Y',年”和“M',月”)需要特别处理,因为它们代表的时间长短取决于使用时间。虽然timedelta日单位相当于24小时,但无法将月份单位转换为天,因为不同的月份有不同的天数

跨度的长度是64位整数乘以日期或单位长度的范围。例如,“W”(周)的时间跨度正好比“D”(天)的时间跨度长7倍,而“D”(天)的时间跨度正好比“h”(小时)的时间跨度长24倍

因此,时间增量适用于小时、周、月、日,因为它们是不可变的时间跨度。然而,月份和年份的长度是可变的(想想闰年),因此要考虑到这一点,
numpy
需要某种“平均”(我猜)。一个
numpy
“年”似乎是一年5小时49分12秒,而一个
numpy
“月”似乎是30天10小时29分6秒

# Adding one numpy month adds 30 days + 10:29:06:
deltaGap = np.timedelta64(1,'M')
date+deltaGap
# Timestamp('2013-01-31 10:29:06', freq='10MS')

# Adding one numpy year adds 1 year + 05:49:12:
deltaGap = np.timedelta64(1,'Y')
date+deltaGap
# Timestamp('2014-01-01 05:49:12', freq='10MS')
这不是很容易处理的,这就是为什么我只想转到
relativedelta
,它(对我来说)更直观。

您可以尝试使用它,它主要用于在日期格式上应用偏移逻辑(月、年、小时)

# get random dates
dates = pd.date_range(start = '1/1/2013', freq='H',periods=100,closed='left', normalize=True)

#take first date as example
date = dates[0]

# subtract a month
dates[0] - pd.DateOffset(months=1)
Timestamp('2012-12-01 00:00:00')

# to apply this on all dates
new_dates = list(map(lambda x: x - pd.DateOffset(months=1), dates))

非常感谢。这很有道理。在寻找解决方法时,不知何故错过了relativedelta!是的,有点奇怪。我喜欢
numpy
文档的这一部分:“没有办法将月份单位转换为天,因为不同的月份有不同的天数”
relativedelta
显然做到了不可能的事情!
# Adding one numpy month adds 30 days + 10:29:06:
deltaGap = np.timedelta64(1,'M')
date+deltaGap
# Timestamp('2013-01-31 10:29:06', freq='10MS')

# Adding one numpy year adds 1 year + 05:49:12:
deltaGap = np.timedelta64(1,'Y')
date+deltaGap
# Timestamp('2014-01-01 05:49:12', freq='10MS')
# get random dates
dates = pd.date_range(start = '1/1/2013', freq='H',periods=100,closed='left', normalize=True)

#take first date as example
date = dates[0]

# subtract a month
dates[0] - pd.DateOffset(months=1)
Timestamp('2012-12-01 00:00:00')

# to apply this on all dates
new_dates = list(map(lambda x: x - pd.DateOffset(months=1), dates))