web-dev-qa-db-fra.com

Python numpy: ne peut pas convertir datetime64 [ns] en datetime64 [D] (à utiliser avec Numba)

Je veux passer un tableau datetime à une fonction Numba (qui ne peut pas être vectorisée et serait sinon très lente). Je comprends que Numba prend en charge numpy.datetime64. Cependant, il semble qu'il supporte datetime64 [D] (précision jour) mais pas datetime64 [ns] (précision milliseconde) (j'ai appris cela à la dure: est-ce documenté?).

J'ai essayé de convertir de datetime64 [ns] en datetime64 [D], mais je n'arrive pas à trouver un moyen! Des idées?

J'ai résumé mon problème avec le code minimal ci-dessous. Si vous exécutez testdf(mydates), qui est datetime64 [D], cela fonctionne très bien. Si vous exécutez testdf(dates_input), qui est datetime64 [ns], ce n'est pas le cas. Notez que cet exemple passe simplement les dates à la fonction Numba, qui ne fait (encore) rien avec elles. J'essaie de convertir dates_input en datetime64 [D], mais la conversion ne fonctionne pas. Dans mon code d'origine, j'ai lu à partir d'une table SQL dans un pandas dataframe, et j'ai besoin d'une colonne qui change le jour de chaque date au 15ème.

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)

L'erreur que j'obtiens si j'exécute testdf(dates_input) est:

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

Series.astype Convertit tous les objets de type date en datetime64[ns]. Pour convertir en datetime64[D], Utilisez values pour obtenir un tableau NumPy avant d'appeler astype:

dates_input = df["month_15"].values.astype('datetime64[D]')

Notez que les NDFrames (tels que Series et DataFrames) ne peuvent contenir que des objets de type datetime en tant qu'objets de type datetime64[ns]. La conversion automatique de tous les goûts datetime en un type commun simplifie les calculs de date ultérieurs. Mais cela rend impossible de stocker, disons, datetime64[s] Objets dans une colonne DataFrame. Pandas développeur principal, Jeff Reback explique ,

"Nous n'autorisons pas les conversions directes car il est tout simplement trop compliqué de conserver autre chose que datetime64 [ns] en interne (ni nécessaire du tout)."


Notez également que même si df['month_15'].astype('datetime64[D]') a dtype datetime64[ns]:

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

lorsque vous parcourez les éléments de la série, vous obtenez pandas Timestamps, pas 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')]

Par conséquent, il n'est pas clair que Numba ait réellement un problème avec datetime64[ns], Il pourrait simplement avoir un problème avec Timestamps. Désolé, je ne peux pas vérifier cela - je n'ai pas installé Numba.

Cependant, il peut être utile d’essayer

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

puisque df['month_15'].astype('datetime64[D]').values est vraiment un tableau NumPy de dtype datetime64[ns]:

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

Si cela fonctionne, vous n'avez pas besoin de tout convertir en datetime64[D], Il vous suffit de passer des tableaux NumPy - pas Pandas Series - to testf.

30
unutbu