如何通过pyarrow用用户定义的模式编写Parquet

时间:2019-07-11 04:30:00

标签: python-3.x pyarrow

当我执行以下代码时-出现以下错误 ValueError:表架构与用于创建文件的架构不匹配

import pandas as pd
import pyarrow as pa
import pyarrow.parquet as pq


fields = [
    ('one', pa.int64()),
    ('two', pa.string(), False),
    ('three', pa.bool_())
]
schema = pa.schema(fields)

schema = schema.remove_metadata()
df = pd.DataFrame(
    {
        'one': [2, 2, 2],
        'two': ['foo', 'bar', 'baz'],
        'three': [True, False, True]
    }
)

df['two'] = df['two'].astype(str)

table = pa.Table.from_pandas(df, schema, preserve_index=False).replace_schema_metadata()
writer = pq.ParquetWriter('parquest_user_defined_schema.parquet', schema=schema)
writer.write_table(table)

1 个答案:

答案 0 :(得分:0)

这对于最新版本的pyarrow(> = 0.14.0)正常工作,但我可以确认pyarrow 0.13也出现错误。

原因是在从熊猫到箭头的转换中未保留模式的可空性的错误(请参见https://issues.apache.org/jira/browse/ARROW-5169)。

使用pyarrow 0.13:

>>> schema.field_by_name('two').nullable
False

>>> table.schema.field_by_name('two').nullable
True

这使得您指定的schema与传递给write_table的表的模式不匹配,从而导致出现错误。
该问题已在0.14中修复,并且两者都将在上面的输出中给出False

因此,您可以在手动创建模式时删除nullable=False,或更新为箭头> = 0.14。


请注意,您是将单个表写入单个Parquet文件中,不需要手动指定架构(将pandas DataFrame转换为arrow Table时已指定了架构,而pyarrow将使用表写到镶木地板)。因此,在简单的情况下,您也可以这样做:

pq.write_table(table, 'parquest_user_defined_schema.parquet')

附加说明:您需要输入writer.close()才能完成示例。