Python numpy:无法将 datetime64[ns] 转换为 datetime64[D](与 Numba 一起使用)

Python numpy: cannot convert datetime64[ns] to datetime64[D] (to use with Numba)

我想将日期时间数组传递给 Numba 函数(无法矢量化,否则会非常慢)。我了解 Numba 支持 numpy.datetime64。但是,它似乎支持 datetime64[D](天精度)但不支持 datetime64[ns](毫秒精度)(我很难学到这一点:是否有记录?)。

我尝试将 datetime64[ns] 转换为 datetime64[D],但似乎找不到方法!有什么想法吗?

我用下面的最少代码总结了我的问题。如果你 运行 testdf(mydates),也就是 datetime64[D],它工作正常。如果你 运行 testdf(dates_input),也就是 datetime64[ns],它就不会。请注意,此示例只是将日期传递给 Numba 函数,该函数(尚未)对它们执行任何操作。我尝试将 dates_input 转换为 datetime64[D],但转换不起作用。在我的原始代码中,我从 SQL table 读取到 pandas 数据框,并且需要一个将每个日期的日期更改为 15 号的列。

import numba
import numpy as np
import pandas as pd
import datetime

mydates =np.array(['2010-01-01','2011-01-02']).astype('datetime64[D]')
df=pd.DataFrame()
df["rawdate"]=mydates
df["month_15"] = df["rawdate"].apply(lambda r: datetime.date( r.year, r.month,15 ) )

dates_input = df["month_15"].astype('datetime64[D]')
print dates_input.dtype # Why datetime64[ns] and not datetime64[D] ??


@numba.jit(nopython=True)
def testf(dates):
    return 1

print testf(mydates)

如果我 运行 testdf(dates_input) 我得到的错误是:

numba.typeinfer.TypingError: Failed at nopython (nopython frontend)
Var 'dates' unified to object: dates := {pyobject}

Series.astype 将所有类似日期的对象转换为 datetime64[ns]。 要转换为 datetime64[D],请在调用 astype:

之前使用 values 获取 NumPy 数组
dates_input = df["month_15"].values.astype('datetime64[D]')

请注意,NDFrame(例如 Series 和 DataFrames)只能将类似日期时间的对象保存为 dtype datetime64[ns] 的对象。所有类似日期时间的自动转换为通用数据类型简化了后续日期计算。但这使得无法在 DataFrame 列中存储 datetime64[s] 个对象。 Pandas 核心开发人员,Jeff Reback explains

"We don't allow direct conversions because its simply too complicated to keep anything other than datetime64[ns] internally (nor necessary at all)."


另请注意,即使 df['month_15'].astype('datetime64[D]') 具有 dtype datetime64[ns]:

In [29]: df['month_15'].astype('datetime64[D]').dtype
Out[29]: dtype('<M8[ns]')

当您循环访问系列中的项目时,您会得到 pandas Timestamps,而不是 datetime64[ns]s。

In [28]: df['month_15'].astype('datetime64[D]').tolist()
Out[28]: [Timestamp('2010-01-15 00:00:00'), Timestamp('2011-01-15 00:00:00')]

因此,目前还不清楚Numba到底是不是datetime64[ns]有问题,可能只是Timestamps有问题。抱歉,我无法检查 - 我没有安装 Numba。

但是,尝试一下可能对您有用

testf(df['month_15'].astype('datetime64[D]').values)

因为 df['month_15'].astype('datetime64[D]').values 确实是 dtype datetime64[ns]:

的 NumPy 数组
In [31]: df['month_15'].astype('datetime64[D]').values.dtype
Out[31]: dtype('<M8[ns]')

如果可行,那么您不必将所有内容都转换为 datetime64[D],您只需将 NumPy 数组(而非 Pandas 系列)传递给 testf

运行 在计算两个日期之间的工作日数时出现相同的错误:

from pandas.tseries.offsets import MonthBegin
import numpy as np 

# Calculate the beginning of the month from a given date
df['Month_Begin'] = pd.to_datetime(df['MyDateColumn'])+ MonthBegin(-1)

# Calculate # of Business Days
# Convert dates to string to prevent type error [D]
df['TS_Period_End_Date'] = df['TS_Period_End_Date'].dt.strftime('%Y-%m-%d')
df['Month_Begin'] = df['Month_Begin'].dt.strftime('%Y-%m-%d')

df['Biz_Days'] = np.busday_count(df['Month_Begin'], df['MyDateColumn']) #<-- Error if not converted into strings.

我的解决方法是使用“.dt.strftime(''%Y-%m-%d')”转换日期。它在我的特殊情况下有效。