You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何强制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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 19:05:10