使用Pandas读取Parquet文件遇timestamp越界错误,求解决办法
解决Parquet时间戳越界读取错误的三种方案
你遇到的错误是因为Parquet文件中存在超出Pandas时间戳范围的微秒级时间戳:33106123800000000(换算后是远未来的时间,超过了Pandas支持的纳秒级时间戳上限)。以下是三种解决思路:
一、定位违规行
直接用Pandas读取会触发报错,所以先通过PyArrow读取原始数据,筛选出异常行:
import pyarrow.parquet as pq # 读取Parquet为Arrow表 table = pq.read_table('fhv_tripdata_2019-02.parquet') # 自动识别所有微秒级时间戳字段 timestamp_cols = [col.name for col in table.schema if str(col.type) == 'timestamp[us]'] # 遍历字段找出异常行 for col_name in timestamp_cols: # Pandas支持的最大纳秒时间戳对应微秒值:2262-04-11 23:47:16.854775807 max_valid_us = 2262041123471685 # 筛选出超出范围的行 invalid_mask = table[col_name] > max_valid_us invalid_rows = table.filter(invalid_mask) print(f"字段「{col_name}」的异常行数量:{invalid_rows.num_rows}") # 导出异常行到CSV方便查看 invalid_rows.to_pandas().to_csv(f'invalid_{col_name}_rows.csv', index=False)
二、强制转换并替换异常值
如果需要保留所有行,可以将异常时间戳替换为合法值(比如NaT)后再转换为DataFrame:
import pyarrow.parquet as pq import pyarrow.compute as pc table = pq.read_table('fhv_tripdata_2019-02.parquet') timestamp_cols = [col.name for col in table.schema if str(col.type) == 'timestamp[us]'] max_valid_us = 2262041123471685 for col_name in timestamp_cols: # 将超出范围的时间戳替换为NaT cleaned_col = pc.if_else(pc.greater(table[col_name], max_valid_us), None, table[col_name]) # 更新表中的字段 table = table.set_column(table.schema.get_field_index(col_name), col_name, cleaned_col) # 转换为Pandas DataFrame df = table.to_pandas()
三、读取时直接忽略异常行
通过PyArrow的过滤功能,在读取阶段就剔除时间戳超出范围的行:
import pyarrow.parquet as pq import pyarrow.compute as pc table = pq.read_table('fhv_tripdata_2019-02.parquet') timestamp_cols = [col.name for col in table.schema if str(col.type) == 'timestamp[us]'] max_valid_us = 2262041123471685 # 构建过滤条件:所有时间戳字段都在合法范围内 filter_expr = None for col_name in timestamp_cols: col_filter = pc.less_equal(table[col_name], max_valid_us) filter_expr = col_filter if filter_expr is None else pc.and_(filter_expr, col_filter) # 过滤后转成DataFrame df = table.filter(filter_expr).to_pandas()
内容的提问来源于stack exchange,提问作者Michael
相关产品推荐
相关产品推荐

