使用fastparquet/pyarrow读取Parquet文件时时间戳溢出问题求助
问题:Parquet文件时间解析异常及引擎报错处理
问题现象
从S3读取Parquet文件时,某列中的2022-10-06 00:00:00被错误解析为1970-01-20 06:30:14.400,但同列的2022-09-01 00:00:00解析正常。切换引擎时出现以下报错:
pyarrow引擎报错
pyarrow error: pyarrow.lib.ArrowInvalid: Casting from timestamp[us] to timestamp[ns] would result in out of bounds timestamp: 101999952000000000
fastparquet引擎报错
OverflowError: value too large Exception ignored in: 'fastparquet.cencoding.time_shift' OverflowError: value too large OverflowError: value too large
相关代码
s3_client = boto3.client('s3') obj = s3_client.get_object(Bucket="blah", Key="blah1") df=pd.read_parquet(io.BytesIO(obj['Body'].read()),engine="fastparquet")
解决方案
1. 检查Parquet文件的时间戳元数据
先确认目标列的时间戳类型和单位是否匹配实际存储,用pyarrow读取元信息:
import pyarrow.parquet as pq import io import boto3 s3_client = boto3.client('s3') obj = s3_client.get_object(Bucket="blah", Key="blah1") parquet_file = pq.ParquetFile(io.BytesIO(obj['Body'].read())) # 打印Schema,查看目标列的时间戳定义,比如是否是timestamp[us]/[ms]/[ns] print(parquet_file.schema)
2. 用pyarrow读取时指定正确的时间戳类型
如果元数据标记的时间单位和实际存储数值不符,手动指定Schema读取:
import pyarrow as pa import pyarrow.parquet as pq import io import boto3 import pandas as pd s3_client = boto3.client('s3') obj = s3_client.get_object(Bucket="blah", Key="blah1") # 替换成你的列名和正确的时间单位,比如实际是ms就写'ms' custom_schema = pa.schema([ ('your_date_column', pa.timestamp('ms')) ]) # 按指定Schema读取 table = pq.read_table(io.BytesIO(obj['Body'].read()), schema=custom_schema) df = table.to_pandas()
3. 手动修复错误的时间戳数值
如果是存储时单位错误(比如把毫秒(ms)误存为微秒(us)),读取后调整数值:
import pandas as pd import numpy as np # 假设错误列名为date_col,解析后数值是实际的1000倍,需除以1000转成正确的纳秒值 df['date_col'] = pd.to_datetime(df['date_col'].astype(np.int64) // 1000, unit='ns')
4. fastparquet读取时指定时间单位
尝试给fastparquet指定time_unit参数,匹配实际存储的时间单位:
df = pd.read_parquet(io.BytesIO(obj['Body'].read()), engine="fastparquet", time_unit='ms')
内容的提问来源于stack exchange,提问作者Bill
相关产品推荐
相关产品推荐

