dask 数据框如何将列转换为 to_datetime
dask dataframe how to convert column to to_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,但到目前为止 none 它们都有效。
谢谢你,感谢你的指导,
更新
我将在此处包含新的错误消息:
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
此外,我希望能够在日期中指定格式,就像我在 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)
我不确定这种做法是否正确
使用astype
您可以使用 astype
方法将系列的 dtype 转换为 NumPy dtype
df.time.astype('M8[us]')
可能还有一种方法可以指定 Pandas 样式数据类型(欢迎编辑)
使用map_partitions和meta
当使用 map_partitions
等黑盒方法时,dask.dataframe 需要知道输出的类型和名称。 map_partitions
.
的文档字符串中列出了一些方法可以做到这一点
您可以提供一个具有正确数据类型和名称的空 Pandas 对象
meta = pd.Series([], name='time', dtype=pd.Timestamp)
或者您可以为 Series 提供 (name, dtype)
的元组或为 DataFrame 提供字典
meta = ('time', pd.Timestamp)
那应该没问题
df.time.map_partitions(pd.to_datetime, meta=meta)
如果您在 df
上调用 map_partitions
,那么您需要为所有内容提供数据类型。但在您的示例中并非如此。
我不确定这是否是正确的方法,但映射列对我有用:
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]'))
Dask 也带有 to_timedelta,所以这应该也可以。
df['time']=dd.to_datetime(df.time,unit='ns')
单元采用的值与pandas中的pd.to_timedelta相同。这可以找到 here.
如果日期时间是 非 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 秒 ± 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 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.astype('M8[s]')
ddf.compute()
每个循环 1 分钟 8 秒 ± 3.65 秒(7 次运行的平均值 ± 标准偏差,每次 1 个循环)
我正在尝试将我的数据框的一列转换为日期时间。在此处的讨论 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,但到目前为止 none 它们都有效。
谢谢你,感谢你的指导,
更新
我将在此处包含新的错误消息:
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
此外,我希望能够在日期中指定格式,就像我在 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)
我不确定这种做法是否正确
使用astype
您可以使用 astype
方法将系列的 dtype 转换为 NumPy dtype
df.time.astype('M8[us]')
可能还有一种方法可以指定 Pandas 样式数据类型(欢迎编辑)
使用map_partitions和meta
当使用 map_partitions
等黑盒方法时,dask.dataframe 需要知道输出的类型和名称。 map_partitions
.
您可以提供一个具有正确数据类型和名称的空 Pandas 对象
meta = pd.Series([], name='time', dtype=pd.Timestamp)
或者您可以为 Series 提供 (name, dtype)
的元组或为 DataFrame 提供字典
meta = ('time', pd.Timestamp)
那应该没问题
df.time.map_partitions(pd.to_datetime, meta=meta)
如果您在 df
上调用 map_partitions
,那么您需要为所有内容提供数据类型。但在您的示例中并非如此。
我不确定这是否是正确的方法,但映射列对我有用:
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]'))
Dask 也带有 to_timedelta,所以这应该也可以。
df['time']=dd.to_datetime(df.time,unit='ns')
单元采用的值与pandas中的pd.to_timedelta相同。这可以找到 here.
如果日期时间是 非 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 秒 ± 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 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.astype('M8[s]')
ddf.compute()
每个循环 1 分钟 8 秒 ± 3.65 秒(7 次运行的平均值 ± 标准偏差,每次 1 个循环)