如何读写/追加含非固定结构字典的Pandas DataFrame到Parquet?
问题:PyArrow追加动态字典字段到Parquet时的类型不匹配
我们的应用需要将DataFrame片段追加到Parquet存储,但以下代码加载时会因类型不匹配失败:
import pyarrow as pa import pyarrow.parquet as pq import pandas as pd df_test1 = pd.DataFrame({'a': [1, 2], 'b': [{'k1': 0, 'k2':1}, {'k3': 'ok'}]}) df_test2 = pd.DataFrame({'a': [1, None], 'b': [{'k1': None}, {'k3': None}]}) pq_dir = "/tmp/test.pq" for _df in [df_test1, df_test2]: pa_data = pa.Table.from_pandas(_df) display(pa_data) pq.write_to_dataset(pa_data,root_path=pq_dir) pd.read_parquet(pq_dir)
原因分析
df_test1转换后的表结构:
pyarrow.Table a: double b: struct<k1: int64, k2: int64, k3: string> child 0, k1: int64 child 1, k2: int64 child 2, k3: string
df_test2转换后的schema:
pyarrow.Table a: double b: struct<k1: null, k3: null> child 0, k1: null child 1, k3: null
由于字典字段b的键名、值类型完全无约束(仅要求键为字符串),无法提前定义统一的schema来匹配所有数据。
现有解决方案的局限性
方案1:全量读取合并
pd.concat(d.to_table().to_pandas() for d in pa.dataset.dataset(pq_dir).get_fragments())
该方法必须读取整个数据集,无法支持按行范围(第N到M行)读取,处理超大型数据时完全不现实。
方案2:字典转JSON存储
直接将字典序列化为JSON字符串存储,但JSON序列化/反序列化效率低,会大量浪费内存,性能表现差。
方案3:fastparquet库
fastparquet可以轻松处理该场景:
import fastparquet df_test1 = pd.DataFrame({'a': [1., 2], 'b': [{'k1': 0, 'k2':1}, {'k3': 'ok'}]}) df_test2 = pd.DataFrame({'a': [1., None], 'b': [{'k1': None}, {'k3': None}]}) pq_dir = "/tmp/test1.pq" for _i, _df in enumerate([df_test1, df_test2]): fastparquet.write(pq_dir, _df, file_scheme="hive", append=_i>0) fastparquet.ParquetFile(pq_dir).to_pandas()
但fastparquet代码质量尚不成熟,其本质是将字典对象自动转换为纯文本JSON存储:
<pyarrow._parquet.ParquetSchema object at 0x7f6f80d9fd00> required group field_id=-1 schema { optional double field_id=-1 a; optional binary field_id=-1 b (JSON); }
读取时得到的是JSON字符串:
pqt = pq.read_table('/tmp/test1.pq') pqt[1][1].as_py().decode() # '{"k3":"ok"}'
这种方式效率极低,远不如使用jsonb或bson格式存储。
核心矛盾与疑问
PyArrow本质期望数据遵循固定schema的关系型模型,尽管Parquet本身支持schema演进。值得注意的是,PyArrow的R API中concat_table提供了unify_schema=True的选项,但Python API并未暴露该功能,存在明显的功能缺失。
PyArrow无法像多数类SQL数据库那样良好处理单元格内的字典或数组类型。那么,对于需要非关系型数据模型的场景,PyArrow是不是一个不合适的选择?
内容的提问来源于stack exchange,提问作者Wang
相关产品推荐
相关产品推荐

