web-dev-qa-db-ja.com

Python numpy:datetime64 [ns]をdatetime64 [D]に変換できません(Numbaで使用するため))

Datetime配列をNumba関数に渡したい(ベクトル化できず、そうでなければ非常に遅くなる)。 Numbaがnumpy.datetime64をサポートしていることを理解しています。ただし、datetime64 [ns](ミリ秒精度)ではなくdatetime64 [D](日精度)をサポートしているようです(これは難しい方法で学習しました:文書化されていますか?)。

Datetime64 [ns]からdatetime64 [D]に変換しようとしましたが、方法が見つからないようです。何か案は?

私の問題を以下の最小限のコードでまとめました。 datetime64 [D]であるtestdf(mydates)を実行すると、正常に機能します。 datetime64 [ns]であるtestdf(dates_input)を実行すると、実行されません。この例では、日付をNumba関数に渡すだけです。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}
_
19

_Series.astype_は、すべての日付のようなオブジェクトを_datetime64[ns]_に変換します。 _datetime64[D]_に変換するには、valuesを使用してからastypeを呼び出す前にNumPy配列を取得します。

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

NDFrame(シリーズやデータフレームなど)は、dtype _datetime64[ns]_のオブジェクトとして、日時に似たオブジェクトのみを保持できることに注意してください。すべてのdatetime-likesを共通の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]')
_

シリーズのアイテムを反復処理すると、_datetime64[ns]_ sではなくpandas Timestampsが返されます。

_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 Series)ではなくtestfに渡します。 。

30
unutbu