PyArrow读取Parquet文件遇Malformed levels错误,需解析嵌套列
解决Parquet多层嵌套列读取异常的方法
问题背景
目标Parquet文件不可修改,使用PyArrow读取时触发OSError: Malformed levels. min: 102 max: 162 out of range. Max Level: 1;切换fastparquet引擎则报ValueError: buffer is smaller than requested size。文件内column_1和column_2嵌套在多层list结构中,单独读取提示字段不存在,读取外层list列仍报错;fastparquet可读取外层list列但无法识别嵌套结构,返回全None值。经parquet-tools校验,column_1的max_definition_level为4,存在四层嵌套。
方法一:PyArrow低级API手动解析嵌套结构
PyArrow高级API对异常嵌套结构兼容性有限,可直接操作文件元数据与数据缓冲区:
- 打开Parquet文件并获取句柄:
import pyarrow.parquet as pq parquet_file = pq.ParquetFile("target_file.parquet")- 提取目标嵌套列的元信息:
从parquet_file.schema中定位包含column_1、column_2的外层list列,获取其定义层级(definition_levels)、重复层级(repetition_levels)的缓冲区,以及数据页的原始二进制数据。
- 提取目标嵌套列的元信息:
- 手动映射层级与数据:
根据max_definition_level=4的规则,遍历层级数组判断每个数据点的嵌套深度,逐层构建多层list结构,最终提取column_1和column_2的有效值。
- 手动映射层级与数据:
方法二:关闭PyArrow的层级严格校验
若确认文件数据逻辑正确仅元数据标记异常,可关闭PyArrow的层级校验规则:
import pyarrow.parquet as pq # 配置读取选项,关闭层级严格校验 read_opts = pq.ReadOptions(strict_levels=False) table = pq.read_table("target_file.parquet", read_options=read_opts) # 从读取到的外层list列中逐层提取嵌套字段 list_col = table["outer_list_column"] # 依据四层嵌套结构,逐步展开至column_1和column_2
方法三:fastparquet结合原始数据修复
fastparquet返回全None是因为无法识别嵌套结构,可读取原始数据后手动解析:
- 读取文件原始数据块:
import fastparquet as fp pf = fp.ParquetFile("target_file.parquet") raw_col_data = pf.columns["outer_list_column"].to_pandas()- 解析二进制数据重构结构:
参考parquet-tools给出的max_definition_level=4,拆分原始数据中的层级标记与实际数据部分,按照Parquet嵌套编码规则重构多层结构,提取目标字段。
- 解析二进制数据重构结构:
内容的提问来源于stack exchange,提问作者Tom Bomer
相关产品推荐
相关产品推荐

