
Pandas 的 read_parquet 不支持原生 datetime.time 类型作为 DataFrame 列名,保存时会报错;解决方法是将 time 对象预转换为字符串格式再写入 Parquet 文件。
pandas 的 `read_parquet` 不支持原生 `datetime.time` 类型作为 dataframe 列名,保存时会报错;解决方法是将 time 对象预转换为字符串格式再写入 parquet 文件。
Parquet 是一种高效、列式存储的二进制格式,被广泛用于大数据场景下的 Pandas 数据持久化。然而,其底层(如 PyArrow)对数据类型的兼容性有明确限制——datetime.time 对象不被识别为合法的 schema 类型,因此当将其直接用作 DataFrame 的列名(即字典键)并调用 to_parquet() 时,虽能短暂完成序列化(因列名本身不参与 Parquet schema 定义),但在后续 read_parquet() 过程中,Pandas 尝试重建索引/列结构时会触发类型推断失败,最终抛出 TypeError: data type 'time' not understood。
根本原因在于:Parquet 格式规范不定义 time 类型的列元数据,而 Pandas 在反序列化时依赖列名对应的“伪类型”信息进行一致性校验(尤其在含复杂索引或非标准键时)。因此,列名必须是 Parquet 可无歧义表示的类型,如字符串、数字或布尔值。
✅ 推荐解决方案:在构造 DataFrame 前,统一将 time 对象转为 ISO 格式字符串(如 '09:00:00'):
from datetime import time
import pandas as pd
# 正确做法:列名使用 str(time)
df = pd.DataFrame(
index=['ABC', 'DEF'],
data={
str(time(9, 0)): [2, 4], # → '09:00:00'
str(time(10, 30)): [6, 8] # → '10:30:00'
}
)
df.to_parquet('schedule.parquet')
df_restored = pd.read_parquet('schedule.parquet')
print(df_restored)
# 输出:
# 09:00:00 10:30:00
# ABC 2 6
# DEF 4 8
⚠️ 注意事项:
- 不要尝试用
pd.to_datetime().dt.time或astype('category')等方式“包装”列名——列名是 Python 字典键,类型转换必须发生在构造 DataFrame 之前; - 若需后续按时间逻辑操作列名,可利用
pd.to_datetime(df.columns, format='%H:%M:%S').time恢复为time对象; - 避免使用
object类型列名(如混入time和str),否则 Parquet 写入可能静默降级为字符串,但读取行为不可控; - 如涉及多层级索引或时间序列分析,更建议将时间维度作为独立列(
dtype='datetime64[ns]')而非列名,以获得完整的时间算子支持。
总结:Parquet 的设计目标是高性能与跨系统兼容性,因此牺牲了对 Python 特有类型(如 time、Path、自定义类)的直接支持。坚持“列名字符串化、数据列类型标准化”原则,即可安全、高效地使用 read_parquet/to_parquet 流程。










