dask dataframe如何将列转换为to_datetime

时间:2016-09-20 00:50:15

标签: python pandas dask

我正在尝试将我的数据帧的一列转换为datetime。在此处讨论后https://github.com/dask/dask/issues/863我尝试了以下代码:

import dask.dataframe as dd
df['time'].map_partitions(pd.to_datetime, columns='time').compute()

但是我收到以下错误消息

ValueError: Metadata inference failed, please provide `meta` keyword

我应该在meta下面放一个什么?我应该在df中或仅在'time'列中放置所有列的字典吗?我应该放什么类型的?我已经尝试过dtype和datetime64,但到目前为止它们都没有。

谢谢你,我感谢你的指导,

更新

我将在此处添加新的错误消息:

1)使用时间戳

df['trd_exctn_dt'].map_partitions(pd.Timestamp).compute()

TypeError: Cannot convert input to Timestamp

2)使用datetime和meta

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

此外,我希望能够在日期中指定格式,就像我在pandas中所做的那样:

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)

我不确定这是否是正确的方法

5 个答案:

答案 0 :(得分:10)

使用astype

您可以使用astype方法将系列的dtype转换为NumPy dtype

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

可能还有一种指定Pandas样式dtype的方法(编辑欢迎)

使用map_partitions和meta

当使用像map_partitions这样的黑盒方法时,dask.dataframe需要知道输出的类型和名称。在map_partitions的文档字符串中列出了几种方法。

您可以使用正确的dtype和名称

提供空的Pandas对象
meta = pd.Series([], name='time', dtype=pd.Timestamp)

或者您可以为系列提供(name, dtype)元组或为DataFrame提供字典

meta = ('time', pd.Timestamp)

然后一切都会好起来

df.time.map_partitions(pd.to_datetime, meta=meta)

如果您在map_partitions上呼叫df,那么您需要为所有内容提供dtypes。但是在你的例子中并非如此。

答案 1 :(得分:4)

我不确定这是否是正确的方法,但映射列对我有用:

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

答案 2 :(得分:2)

Dask还附带了to_timedelta,因此它也应该工作。

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

取值单位与pandas中的pd.to_timedelta相同。可以找到here

答案 3 :(得分:1)

这对我有用

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

答案 4 :(得分:0)

如果日期时间采用非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毫秒(平均±标准偏差,共运行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 s±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分钟8s±3.65 s(平均±标准偏差,共运行7次,每个循环1次)

相关问题