web-dev-qa-db-ja.com

列をto_datetimeに変換する方法

データフレームの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)

それが正しいアプローチであるかどうかはわかりません

12
dleal

astypeを使用

astypeメソッドを使用して、シリーズのdtypeをNumPy dtypeに変換できます

df.time.astype('M8[us]')

Pandas style dtypeも指定する方法があるでしょう(編集を歓迎します)

Map_partitionsとmetaを使用する

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)

代わりにdfmap_partitionsを呼び出す場合は、すべてのdtypeを提供する必要があります。しかし、あなたの例ではそうではありません。

12
MRocklin

Daskにはto_timedeltaも付属しているので、これも機能するはずです。

df['time']=dd.to_datetime(df.time,unit='ns')

単位の値は、パンダのpd.to_timedeltaと同じです。これは here で見つかります。

6
Arundathi

これが正しいアプローチかどうかはわかりませんが、列のマッピングがうまくいきました:

df['time'] = df['time'].map(lambda x: pd.to_datetime(x, errors='coerce'))
4
tmsss

これは私のために働いた

ddf["Date"] = ddf["Date"].map_partitions(pd.to_datetime,format='%d/%m/%Y',meta = ('datetime64[ns]'))

2
citynorman

日時が非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ループ)

0
skibee