You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何阻止Pandas将Python datetime转换为datetime64[ns]以导出兼容Azure Data Factory的Parquet文件

问题解答:Pandas DataFrame中保留原生Python datetime并兼容Azure Data Factory读取Parquet

首先得明确一点:Pandas本身没法在DataFrame中直接保留原生datetime.datetime类型的列。这是Pandas的设计决定——它依赖NumPy的datetime64[ns]类型实现时间序列的高效存储和运算,只要你把原生datetime对象放入Series/DataFrame,Pandas就会自动将其转换为datetime64[ns]类型,哪怕用apply逐个转换后赋值回去也一样,这是内置的类型优化逻辑,没法绕过。

不过你的核心需求是让Azure Data Factory(ADF)能正确读取Parquet中的时间列,所以不用纠结在DataFrame里保留原生datetime,而是要从Parquet文件的导出格式入手,让导出的时间类型符合ADF的识别要求。

推荐方案:用PyArrow引擎导出标准Parquet TIMESTAMP类型

ADF对Parquet的标准TIMESTAMP类型支持更好,而Pandas默认导出的时间格式(依赖int96时间戳)可能导致识别问题。我们可以用PyArrow引擎指定导出标准的TIMESTAMP类型:

  1. 先安装PyArrow依赖:
pip install pyarrow
  1. 导出Parquet时指定引擎并关闭int96时间戳:
import pandas as pd

# 假设你的DataFrame是df
df.to_parquet(
    "your_output_file.parquet",
    engine="pyarrow",
    use_deprecated_int96_timestamps=False  # 禁用int96,使用标准TIMESTAMP类型
)

这样导出的Parquet文件中,时间列会以Parquet标准的TIMESTAMP格式存储,ADF就能正确识别了。

备选方案:将时间列存为Object类型(不推荐,仅作参考)

如果你一定要在DataFrame中保留原生datetime对象(虽然对后续处理没太大必要),可以强制将列转为object类型:

# 将时间列转换为原生datetime并存为object类型
df["native_datetime"] = df["timestamp"].apply(lambda x: x.to_pydatetime()).astype("object")

# 验证类型
print(df.dtypes["native_datetime"])  # 输出 object
print(type(df["native_datetime"][0]))  # 输出 <class 'datetime.datetime'>

但要注意:

  • Object类型的列会失去Pandas时间序列的所有高效运算能力
  • 导出Parquet时,PyArrow会将object类型中的datetime序列转为标准TIMESTAMP类型,而fastparquet可能会转为字符串,反而更麻烦,所以还是优先推荐第一种方案。

为什么Pandas会自动转换类型?

Pandas的设计目标是高效处理大规模数据,原生Python datetime.datetime对象是不可变的Python对象,存储和运算效率远低于NumPy的datetime64[ns](后者是基于数值的向量类型)。因此Pandas会自动将原生datetime转换为datetime64[ns],这是内置的优化逻辑,没有办法直接禁用。


内容的提问来源于stack exchange,提问作者Mike Williamson

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 07:57:44