如何强制PyArrow写入时忽略NULL类型并沿用原表Schema类型?
问题
我编写了一段代码,将两部分同结构数据追加写入PyArrow Table。第二次写入失败,原因是col3列被推断为null类型,而文件创建时使用的Schema中该列类型为int64。我清楚原因所在,想了解是否可以强制写入时使用表的原Schema类型,而非从当前数据推断的类型?
代码示例:
import pandas as pd import pyarrow as pa import pyarrow.parquet as pq data = { 'col1': ['A', 'A', 'A', 'B', 'B'], 'col2': [0, 1, 2, 1, 2] } df1 = pd.DataFrame(data) df1['col3'] = 1 df2 = df1.copy() df2['col3'] = pd.NA pat1 = pa.Table.from_pandas(df1) pat2 = pa.Table.from_pandas(df2) writer = pq.ParquetWriter('junk.parquet', pat1.schema) writer.write_table(pat1) writer.write_table(pat2)
错误信息:
Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/opt/anaconda3/lib/python3.10/site-packages/pyarrow/parquet/core.py", line 1094, in write_table raise ValueError(msg) ValueError: Table schema does not match schema used to create file: table: col1: string col2: int64 col3: null -- schema metadata -- pandas: '{"index_columns": [{"kind": "range", "name": null, "start": 0, "' + 578 vs. file: col1: string col2: int64 col3: int64 -- schema metadata -- pandas: '{"index_columns": [{"kind": "range", "name": null, "start": 0, "' + 577
解答
可以强制使用原Schema类型写入,以下是两种可靠方法:
方法一:转换DataFrame时指定原Schema
在将df2转为PyArrow Table时,直接传入初始表的Schema,强制对齐数据类型:
pat2 = pa.Table.from_pandas(df2, schema=pat1.schema)
这样df2的col3会被强制转换为可空int64类型(Arrow中支持带空值的数值类型,与纯null类型本质不同),和文件初始Schema完全匹配,即可正常追加写入。
方法二:提前修正DataFrame的列类型
在给df2的col3赋值pd.NA前,先将列类型设置为pandas的可空整数类型Int64,避免被推断为null类型:
df2 = df1.copy() # 先转换列类型为可空整数,再赋值空值 df2['col3'] = df2['col3'].astype('Int64') df2['col3'] = pd.NA
后续转为Arrow表时,col3会被正确识别为可空int64类型,与原Schema一致。
关键说明
PyArrow中的null类型表示列无有效数据类型且全为空值,而可空int64是带空值标记的数值类型,二者属于不同Schema。通过上述任一方法,都能让第二次写入的表Schema与文件初始Schema对齐,解决写入报错问题。
内容的提问来源于stack exchange,提问作者Gopala
相关产品推荐
相关产品推荐

