如何在Dask中利用分离字段构建datetime类型列?
在Dask中通过分离字段构建Datetime列的问题与解决方法
尝试在Dask中利用year、month、day、hour字段构建datetime类型计算列,但始终未成功。虽然代码执行后显示flight_datetime列为datetime64[ns]类型,但实际存储的是字符串,调用dt.year时会抛出AttributeError: 'Series' object has no attribute 'year'错误。
环境信息
- Python 3.8.10
- pandas==1.5.3
- dask==2023.1.1
- aiohttp==3.8.3
用户尝试代码
数据获取代码
# 数据处理 import dask.dataframe as dd # 数据源URL url = "https://raw.githubusercontent.com/Rdatatable/data.table/master/vignettes/flights14.csv" # 读取示例数据 dtable = dd.read_csv(url) # 打印字段列表 print('示例数据字段列表 : ',dtable.columns)
执行结果:
示例数据字段列表 : Index(['year', 'month', 'day', 'dep_delay', 'arr_delay', 'carrier', 'origin', 'dest', 'air_time', 'distance', 'hour'], dtype='object')
创建字段的尝试代码
# 从year、month、day、hour字段创建datetime列 dtable['flight_datetime'] = dd.to_datetime( (dtable.year *1000000 + dtable.month*10000 + dtable.day*100 + dtable.hour).astype(str), format='%Y%m%d%H', errors='ignore') print('示例数据字段列表 : ',dtable.columns) print('示例数据字段类型 : ',dtable.dtypes) print(dtable.flight_datetime.head()) print(dtable.flight_datetime.dt.year.head())
执行结果:
示例数据字段列表 : Index(['year', 'month', 'day', 'dep_delay', 'arr_delay', 'carrier', 'origin', 'dest', 'air_time', 'distance', 'hour', 'flight_datetime'], dtype='object') 示例数据字段类型 : year int64 month int64 day int64 dep_delay int64 arr_delay int64 carrier object origin object dest object air_time int64 distance int64 hour int64 flight_datetime datetime64[ns] dtype: object 0 2014010109 1 2014010111 2 2014010119 3 2014010107 4 2014010113 Name: flight_datetime, dtype: object AttributeError: 'Series' object has no attribute 'year'
问题原因
问题出在dd.to_datetime的errors='ignore'参数上:当Dask无法按照指定的format='%Y%m%d%H'解析字符串时,会直接返回原字符串而非抛出错误。虽然Dask的元数据显示该列为datetime64[ns],但实际每个分区中的数据仍是字符串类型,导致无法使用dt访问器。
解决方法
方法1:修正字符串格式并移除errors='ignore'
确保拼接的字符串严格符合%Y%m%d%H格式(月、日、小时均为两位),同时移除忽略错误的参数,便于排查解析问题:
# 构造标准格式字符串并转换 dtable['flight_datetime'] = dd.to_datetime( dtable.year.astype(str) + dtable.month.astype(str).str.zfill(2) + dtable.day.astype(str).str.zfill(2) + dtable.hour.astype(str).str.zfill(2), format='%Y%m%d%H' ) # 验证结果 print(dtable.flight_datetime.dtype) # 输出 datetime64[ns] print(dtable.flight_datetime.dt.year.head())
方法2:使用Dask的make_datetime函数(更高效)
直接利用分离的年、月、日、小时字段构造datetime,无需拼接字符串,性能更优:
from dask.dataframe import make_datetime dtable['flight_datetime'] = make_datetime( year=dtable.year, month=dtable.month, day=dtable.day, hour=dtable.hour ) # 验证结果 print(dtable.flight_datetime.dtype) print(dtable.flight_datetime.dt.year.head())
内容的提问来源于stack exchange,提问作者Stephane
相关产品推荐
相关产品推荐

