2015-08-10 12 views
8

Voglio passare un array datetime a una funzione Numba (che non può essere vettorizzata e sarebbe altrimenti molto lenta). Capisco che Numba supporta numpy.datetime64. Tuttavia, sembra supportare datetime64 [D] (precisione del giorno) ma non datetime64 [ns] (precisione millisecondo) (l'ho imparato nel modo più duro: è documentato?).Numpy Python: impossibile convertire datetime64 [ns] in datetime64 [D] (da utilizzare con Numba)

Ho provato a convertire da datetime64 [ns] a datetime64 [D], ma non riesco a trovare un modo! Qualche idea?

Ho riassunto il mio problema con il codice minimo qui sotto. Se si esegue testdf(mydates), che è datetime64 [D], funziona correttamente. Se si esegue testdf(dates_input), che è datetime64 [ns], non è così. Nota che questo esempio passa semplicemente le date alla funzione Numba, che non (ancora) fa qualcosa con loro. Provo a convertire date_input a datetime64 [D], ma la conversione non funziona. Nel mio codice originale ho letto da una tabella SQL in un dataframe panda e ho bisogno di una colonna che cambi il giorno di ogni data al 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) 

L'errore che ottengo se corro testdf(dates_input) è:

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

Questa è una domanda davvero utile, ma per qualche motivo è stato molto difficile trovare solo attraverso la ricerca. Ho ricevuto un errore simile durante il tentativo di utilizzare 'np.busday_count' su dati panda, che diceva:' TypeError: Iterator operando 0 dtype non può essere lanciato da dtype ('

risposta

16

Series.astype converte tutti gli oggetti di data-come datetime64[ns]. Per convertire a datetime64[D], utilizzare values per ottenere un allineamento NumPy prima di chiamare astype:

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

noti che NDFrames (come la serie e DataFrames) può contenere solo gli oggetti datetime simili come oggetti di DTYPE datetime64[ns]. La conversione automatica di tutti i tipi di carattere datetime in un dtype comune semplifica i calcoli delle date successive. Ma rende impossibile memorizzare, ad esempio, gli oggetti datetime64[s] in una colonna DataFrame. Pandas sviluppatore nucleo, 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)."


Si noti inoltre che, anche se df['month_15'].astype('datetime64[D]') ha DTYPE datetime64[ns]:

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

quando si scorrere tra gli elementi della serie, si ottiene panda Timestamps, non 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')] 

Pertanto, non è chiaro che Numba in realtà ha un problema con datetime64[ns], potrebbe solo hanno un problema con Timestamps. Spiacente, non posso controllare questo - Non ho installato Numba.

Tuttavia, potrebbe essere utile per voi di provare

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

dal df['month_15'].astype('datetime64[D]').values è veramente un allineamento NumPy di ​​DTYPE datetime64[ns]:

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

Se funziona, allora non c'è bisogno di convertire tutto in datetime64[D], è sufficiente passare gli array NumPy - non la serie Pandas - a testf.

+1

Grazie! Posso chiedere perché questo è, però? Voglio dire, non riesco a pensare a nessuna ragione logica per cui una data, creata con solo anno, mese e giorno, viene convertita in millisecondi di precisione e non può essere riconvertita in precisione giorno a meno che non si chiamino valori. E 'un errore? O mi manca una ragione fondamentale qui? È documentato da qualche parte? La mia grande frustrazione con Python per l'analisi dei dati (che, sì, lo so, è solo una delle molte cose che Python può fare, ma non mi interessa per gli altri!) È davvero la scarsa qualità della documentazione, specialmente contro una pacchetto commerciale come Matlab –

+0

Panda fa un sacco di cose per te che generalmente sono convenienti. Sfortunatamente, a volte questo significa che finisce per fare cose che pensa sia quello che vuoi (come la conversione di tutte le date in datetime64 [ns]/Timestamps) quando in infatti vuoi qualcos'altro. Non so se questo particolare problema è documentato da qualche parte. – unutbu

+0

non è proprio quello che sta succedendo qui, però. Nel mio esempio, Pandas non deve indovinare di quale precisione ho bisogno (giorno o millisecondo), perché dico esplicitamente a Pandas (.astype (datetime64 ['D']). Sembra più un bug –

Problemi correlati