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

Pyt*_*ous 21 python numpy pandas 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表读入一个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)
Run Code Online (Sandbox Code Playgroud)

我跑的错误testdf(dates_input)是:

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

unu*_*tbu 33

Series.astype将所有类似日期的对象转换为datetime64[ns].要转换为datetime64[D],请values在调用之前使用获取NumPy数组astype:

dates_input = df["month_15"].values.astype('datetime64[D]')
Run Code Online (Sandbox Code Playgroud)

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

"我们不允许直接转换,因为它过于复杂,无法在内部保留除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]')
Run Code Online (Sandbox Code Playgroud)

当你遍历系列中的项目时,你得到的是熊猫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')]
Run Code Online (Sandbox Code Playgroud)

因此,目前尚不清楚Numba是否存在问题datetime64[ns],可能只是存在问题Timestamps.对不起,我无法检查 - 我没有安装Numba.

但是,尝试它可能会有用

testf(df['month_15'].astype('datetime64[D]').values)
Run Code Online (Sandbox Code Playgroud)

因为它df['month_15'].astype('datetime64[D]').values是真正的dtype的NumPy数组datetime64[ns]:

In [31]: df['month_15'].astype('datetime64[D]').values.dtype
Out[31]: dtype('<M8[ns]')
Run Code Online (Sandbox Code Playgroud)

如果这样做,那么你不必将所有内容转换为datetime64[D],你只需要将NumPy数组 - 而不是Pandas系列 - 传递给testf.

  • 在某些地方,Pandas决定将所有类似日期的数据汇集到一个通用数据类型中:`datetime64 [ns]`.这样做有一些好处:它使比较和日期算术更容易.这样做的结果是**没有系列的dtype`datetime64 [D]`**.也许`DF ["month_15"].astype("datetime64 [d]")`应该抛出一个异常,而不是默默转换为`datetime64 [NS]`,但只要大熊猫保持其漏斗一切对datetime64 [ NS]政策,'DF [ 'month_15'].astype( 'datetime64 [d]')`不会返回d型`datetime64 [d]`的系列. (6认同)
  • @Pythonistaan​​onymous:在写完这个答案之后,Pandas的"wesm"写了一篇详细的评论,其中包括支持其他datetime64单元的一些背景故事和问题,在这里:https://github.com/pandas-dev/pandas/issues/7307 #issicecomment-224180563 - 关于该问题的许多评论都与此相关. (3认同)