データフレームの1つの列を日時に変換しようとしています。ここでの議論に従って https://github.com/dask/dask/issues/86 次のコードを試しました:
import dask.dataframe as dd
df['time'].map_partitions(pd.to_datetime, columns='time').compute()
しかし、私は次のエラーメッセージを受け取ります
ValueError: Metadata inference failed, please provide `meta` keyword
正確に何をメタの下に置くべきですか?すべての列の辞書をdfに配置する必要がありますか、それとも 'time'列のみを配置する必要がありますかそして、私はどのタイプを入れるべきですか?私はdtypeとdatetime64を試しましたが、どれも今のところ機能しません。
ありがとう、そして私はあなたの指導に感謝します、
更新
ここに新しいエラーメッセージを含めます。
1)タイムスタンプの使用
df['trd_exctn_dt'].map_partitions(pd.Timestamp).compute()
TypeError: Cannot convert input to Timestamp
2)日時とメタの使用
meta = ('time', pd.Timestamp)
df['time'].map_partitions(pd.to_datetime,meta=meta).compute()
TypeError: to_datetime() got an unexpected keyword argument 'meta'
3)日付時刻のみを使用:2%でスタックする
In [14]: df['trd_exctn_dt'].map_partitions(pd.to_datetime).compute()
[ ] | 2% Completed | 2min 20.3s
また、私はパンダで行うように、日付の形式を指定できるようにしたいと思います:
pd.to_datetime(df['time'], format = '%m%d%Y'
更新2
Dask 0.11に更新した後、metaキーワードに問題がなくなりました。それでも、2GBのデータフレームで2%を超えることはできません。
df['trd_exctn_dt'].map_partitions(pd.to_datetime, meta=meta).compute()
[ ] | 2% Completed | 30min 45.7s
更新3
このようにうまく機能しました:
def parse_dates(df):
return pd.to_datetime(df['time'], format = '%m/%d/%Y')
df.map_partitions(parse_dates, meta=meta)
それが正しいアプローチであるかどうかはわかりません
astype
を使用astype
メソッドを使用して、シリーズのdtypeをNumPy dtypeに変換できます
df.time.astype('M8[us]')
Pandas style dtypeも指定する方法があるでしょう(編集を歓迎します)
map_partitions
などのブラックボックスメソッドを使用する場合、dask.dataframeは出力のタイプと名前を認識する必要があります。これを行う方法はいくつかあり、map_partitions
のdocstringにリストされています。
空のPandasオブジェクトに正しいdtypeと名前を指定できます
meta = pd.Series([], name='time', dtype=pd.Timestamp)
または、シリーズには(name, dtype)
のタプルを、データフレームにはdictを提供できます。
meta = ('time', pd.Timestamp)
その後、すべてがうまくいくはずです
df.time.map_partitions(pd.to_datetime, meta=meta)
代わりにdf
でmap_partitions
を呼び出す場合は、すべてのdtypeを提供する必要があります。しかし、あなたの例ではそうではありません。
Daskにはto_timedeltaも付属しているので、これも機能するはずです。
df['time']=dd.to_datetime(df.time,unit='ns')
単位の値は、パンダのpd.to_timedeltaと同じです。これは here で見つかります。
これが正しいアプローチかどうかはわかりませんが、列のマッピングがうまくいきました:
df['time'] = df['time'].map(lambda x: pd.to_datetime(x, errors='coerce'))
これは私のために働いた
ddf["Date"] = ddf["Date"].map_partitions(pd.to_datetime,format='%d/%m/%Y',meta = ('datetime64[ns]'))
日時が非ISO形式の場合、map_partition
より良い結果が得られます:
import dask
import pandas as pd
from dask.distributed import Client
client = Client()
ddf = dask.datasets.timeseries()
ddf = ddf.assign(datetime=ddf.index.astype(object))
ddf = (ddf.assign(datetime_nonISO = ddf['datetime'].astype(str).str.split(' ')
.apply(lambda x: x[1]+' '+x[0], meta=('object')))
%%timeit
ddf.datetime = ddf.datetime.astype('M8[s]')
ddf.compute()
ループごとに11.3 s±719 ms(7回の実行の平均±標準偏差、各1ループ)
ddf = dask.datasets.timeseries()
ddf = ddf.assign(datetime=ddf.index.astype(object))
ddf = (ddf.assign(datetime_nonISO = ddf['datetime'].astype(str).str.split(' ')
.apply(lambda x: x[1]+' '+x[0], meta=('object')))
%%timeit
ddf.datetime_nonISO = (ddf.datetime_nonISO.map_partitions(pd.to_datetime
, format='%H:%M:%S %Y-%m-%d', meta=('datetime64[s]')))
ddf.compute()
ループあたり8.78秒±599ミリ秒(7回の実行の平均±標準偏差、それぞれ1ループ)
ddf = dask.datasets.timeseries()
ddf = ddf.assign(datetime=ddf.index.astype(object))
ddf = (ddf.assign(datetime_nonISO = ddf['datetime'].astype(str).str.split(' ')
.apply(lambda x: x[1]+' '+x[0], meta=('object')))
%%timeit
ddf.datetime_nonISO = ddf.datetime_nonISO.astype('M8[s]')
ddf.compute()
ループあたり1分8秒±3.65秒(7回の実行の平均±標準偏差、それぞれ1ループ)