Django中pd.to_datetime转日期得时间戳而非datetime对象问题
问题原因及解决办法
核心原因分析
- Django序列化自动转换:执行
pd.to_datetime(df['date'])后,Pandas实际已将列转为datetime64[ns]类型,但后续在Django中传递(如序列化到JSON、模板渲染)时,datetime对象被默认转为毫秒级时间戳——这是Django的默认JSON序列化行为,并非Pandas转换出错。 unit参数误用:补充操作中添加unit='ms'是错误的,该参数仅适用于数字类型的时间戳,而你的输入是字符串格式的日期,自然会触发转换失败报错。- 潜在数据混合格式(低概率):若原
date列的object类型中混有字符串日期和数字时间戳,Pandas可能会统一转为int类型时间戳,但你已确认输入格式一致,此情况概率较低。
解决步骤
步骤1:验证Pandas转换结果
先执行以下代码确认转换后的列类型和实际值:
print(df['date'].dtype) print(df['date'].head())
若输出为datetime64[ns]且显示2015-06-20格式,说明Pandas转换正常,问题出在Django序列化环节。
步骤2:处理Django序列化问题
针对Django自动转时间戳的情况,有两种解决方式:
- 方式一:序列化时指定日期格式
使用Django内置序列化器时,显式指定日期输出格式:
若使用Django REST Framework,可在序列化器中直接配置日期格式:from django.core.serializers.json import DjangoJSONEncoder import json # 将DataFrame转为指定格式的JSON json_data = json.dumps( filled_df.to_dict('records'), cls=DjangoJSONEncoder, ensure_ascii=False, default=lambda x: x.strftime('%Y-%m-%d') if isinstance(x, pd.Timestamp) else x )from rest_framework import serializers class YourDataSerializer(serializers.ModelSerializer): date = serializers.DateField(format="%Y-%m-%d") # 其他字段定义... - 方式二:提前将datetime转为字符串
在数据处理完成后,直接把日期列转为字符串格式,避免后续序列化自动转换:filled_df['date'] = filled_df['date'].dt.strftime('%Y-%m-%d')
步骤3:排查数据格式异常(若步骤1验证失败)
若步骤1发现列类型为int64,说明原数据存在混合格式,可执行以下代码定位异常值:
# 筛选无法转为datetime的行 invalid_rows = df[pd.to_datetime(df['date'], errors='coerce').isna()] print(invalid_rows)
若存在数字时间戳,可统一处理:
# 先将所有值转为字符串 df['date'] = df['date'].astype(str) # 分别处理字符串日期和毫秒时间戳 str_date_mask = df['date'].str.match(r'\d{4}-\d{2}-\d{2}') df.loc[str_date_mask, 'date'] = pd.to_datetime(df.loc[str_date_mask, 'date']) timestamp_mask = df['date'].str.isdigit() df.loc[timestamp_mask, 'date'] = pd.to_datetime(df.loc[timestamp_mask, 'date'], unit='ms')
补充说明
unit参数仅用于将数字类型的时间戳转换为datetime对象,比如处理1434758400000这类数字时才需要指定unit='ms',字符串日期无需使用该参数。
内容的提问来源于stack exchange,提问作者Ocean Vue
相关产品推荐
相关产品推荐

