NumPy日期时间和Pandas日期时间

6
我对numpy和pandas日期对象之间的相互作用感到困惑(或者可能只是对numpy的datetime64感到困惑)。
我尝试使用numpy内置的功能来计算工作日,如下所示:
np.busday_count("2016-03-01", "2016-03-31", holidays=[np.datetime64("28/03/2016")])

然而,显然numpy无法处理倒置的日期格式:
ValueError: Error parsing datetime string "28/03/2016" at position 2

为了解决这个问题,我想使用pandas的to_datetime函数。但是:
np.busday_count("2016-03-01", "2016-03-31", holidays=[np.datetime64(pd.to_datetime("28/03/2016"))])

ValueError: Cannot safely convert provided holidays input into an array of dates

查找了一些资料后,似乎问题的原因是使用to_datetime和np.datetime64进行连接会导致生成一个datetime64[us]对象,而busday_count函数无法接受该类型(这是意料之中的行为还是一个错误?)。因此,我的下一步尝试是:

np.busday_count("2016-03-01", "2016-03-31", holidays=[np.datetime64(pd.Timestamp("28"), "D")])

但是:

TypeError: Cannot cast datetime.datetime object from metadata [us] to [D] according to the rule 'same_kind'

那就是我的问题了 - 为什么所有这些日期时间格式之间存在如此多的不兼容性?我该如何解决这些问题?


1
既然在第一个示例中,其他日期参数都是以YYYY-MM-DD格式传递的,为什么不将第一个示例中的日期字符串转换为2016-03-28呢?例如:'-'.join("28/03/2016".split('/')[::-1]) - mhawke
当然,这是一种方法 - 这只是我的实际应用程序中假日日历的格式,并引发了所有其他问题。因此,我上面的帖子更多地是关于理解实际发生的情况 - 不管怎样,感谢您提供了务实的解决方案! - Nils Gudat
可能是在datetime、Timestamp和datetime64之间进行转换的重复问题。 - ivan_pozdeev
不是解释,但这是另一种方法:pd.to_datetime("28/03/2016").strftime('%F') - mhawke
2个回答

3

我一直遇到类似的问题,使用np.is_busday()

datetime64的类型非常重要。查看numpy datetime文档,您可以指定numpy datetime类型为D。

这样做是有效的:

my_holidays=np.array([datetime.datetime.strptime(x,'%m/%d/%y') for x in holidays.Date.values], dtype='datetime64[D]')

day_flags['business_day'] = np.is_busday(days,holidays=my_holidays)

而这会抛出与您收到的相同的错误:

my_holidays=np.array([datetime.datetime.strptime(x,'%m/%d/%y') for x in holidays.Date.values], dtype='datetime64')

唯一的区别在于指定datetime64的类型。
dtype='datetime64[D]'

vs

dtype='datetime64'

文档在这里:

https://docs.scipy.org/doc/numpy-1.13.0/reference/arrays.datetime.html


0

在使用np.busday_count时,我遇到了同样的问题,后来我发现问题出在将其转换为datetime对象或numpy datetime对象时添加了hoursminutessecondsmilliseconds

我只将其转换为仅包含日期而不是hoursminutessecondsmillisecondsdatetime对象。

以下是我的代码:

holidays_list.json文件:

{
    "holidays_2019": [
        "04-Mar-2019",
        "21-Mar-2019",
        "17-Apr-2019",
        "19-Apr-2019",
        "29-Apr-2019",
        "01-May-2019",
        "05-Jun-2019",
        "12-Aug-2019",
        "15-Aug-2019",
        "02-Sep-2019",
        "10-Sep-2019",
        "02-Oct-2019",
        "08-Oct-2019",
        "28-Oct-2019",
        "12-Nov-2019",
        "25-Dec-2019"
    ],
    "format": "%d-%b-%Y"
}

代码文件

import json
import datetime
import numpy as np

with open('holidays_list.json', 'r') as infile:
    data = json.loads(infile.read())

# the following is where I convert the datetime object to date
holidays = list(map(lambda x: datetime.datetime.strptime(
    x, data['format']).date(), data['holidays_2019']))

start_date = datetime.datetime.today().date()
end_date = start_date + datetime.timedelta(days=30)
holidays = [start_date + datetime.timedelta(days=1)]
print(np.busday_count(start_date, end_date, holidays=holidays))

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接