使用pd.to_parquet保存含pd.Timedelta的DataFrame报错,求排查差异
以下是真实DataFrame和你的示例之间最可能存在的差异,对应排查方法:
列的整体 dtype 不一致
你的示例中"value"列的 dtype 应该是timedelta64[ns],但真实DataFrame的"value"列因为混入其他类型,变成了objectdtype。虽然单个元素是pd.Timedelta,但pyarrow处理object列时不会按时间差类型解析,而是尝试转为通用数值类型,导致报错。
检查命令:print(df['value'].dtype) # 真实数据应该显示object,示例显示timedelta64[ns]列内存在混合类型元素
真实DataFrame的"value"列里,除了pd.Timedelta,可能还混有其他类型的元素(比如字符串、整数、None、numpy的timedelta64标量,甚至pd.NaT对象)。这些异类元素会把列的 dtype 拉成object,导致pyarrow无法统一转换。
检查命令:print(df['value'].apply(type).unique()) # 查看列内所有元素的类型MultiIndex 存在不可序列化的层级类型
虽然报错指向"value"列,但真实DataFrame的MultiIndex可能包含pyarrow不支持的类型(比如自定义Python对象、非标准的时间类型),间接干扰了整个DataFrame的序列化流程。
检查命令:# 逐个检查索引层级的dtype for i in range(df.index.nlevels): print(f"Level {i} dtype: {df.index.get_level_values(i).dtype}")Timedelta 对象存在异常属性
个别pd.Timedelta可能是异常创建的(比如内部存储的nanoseconds值格式异常,或者是被篡改过的对象),虽然表面看是正常的Timedelta,但序列化时无法被pyarrow识别。可以尝试把列转成timedelta64类型,看是否报错:df['value'] = pd.to_timedelta(df['value']) # 若报错,说明存在无法转换的异常元素依赖库版本不一致
你的示例环境和真实环境的pandas、pyarrow版本可能不同,旧版本的pyarrow对object列中的pd.Timedelta支持不完善,导致转换失败。
检查命令:import pandas as pd import pyarrow print(f"Pandas版本: {pd.__version__}") print(f"PyArrow版本: {pyarrow.__version__}")
内容的提问来源于stack exchange,提问作者Andi

