我想将一个日期时间数组传递给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表读入一个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}
答案 0 :(得分:27)
Series.astype
会将所有类似日期的对象转换为datetime64[ns]
。
要转换为datetime64[D]
,请在调用values
之前使用astype
获取NumPy数组:
dates_input = df["month_15"].values.astype('datetime64[D]')
请注意,NDFrame(例如Series和DataFrames)只能将类似日期时间的对象保存为dtype datetime64[ns]
的对象。将所有日期时间自动转换为常见的dtype简化了后续日期计算。但它使得无法在DataFrame列中存储datetime64[s]
个对象。 Pandas核心开发人员Jeff Reback explains,
“我们不允许直接转换,因为它过于复杂,无法在内部保留除datetime64 [ns]以外的任何内容(也根本不需要)。”
另请注意,即使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
。
答案 1 :(得分:1)
计算两个日期之间的工作日数时遇到相同的错误:
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')”转换日期。在我的特定情况下有效。