如何使用pyarrow更改列数据类型

问题描述

我正在读取一组箭头文件并将它们写入镶木地板文件

import pathlib
from pyarrow import parquet as pq
from pyarrow import feather
import pyarrow as pa

base_path = pathlib.Path('../mydata')

fields = [
    pa.field('value',pa.int64()),pa.field('code',pa.dictionary(pa.int32(),pa.uint64(),ordered=False)),]
schema = pa.schema(fields)

with pq.ParquetWriter('sample.parquet',schema) as pqwriter:
    for file_path in base_path.glob('*.arrow'):
        table = feather.read_table(file_path)
        pqwriter.write_table(table)

我的问题是箭头文件中的 code 字段是用 int8 索引而不是 int32 定义的。然而 int8 的范围是不够的。因此,我为镶木地板文件中的字段 int32 定义了一个带有 code 索引的架构。

但是,现在将箭头表写入 parquet 会抱怨模式不匹配。

如何更改箭头列的数据类型?我检查了 pyarrow API 并没有找到更改架构的方法。这可以在不往返熊猫的情况下完成吗?

解决方法

Arrow ChunkedArray 有一个 cast 函数,但不幸的是它不能用于你想做的事情:

>>> table['code'].cast(pa.dictionary(pa.int32(),pa.uint64(),ordered=False))
Unsupported cast from dictionary<values=uint64,indices=int8,ordered=0> to dictionary<values=uint64,indices=int32,ordered=0> (no available cast function for target type)

相反,您可以将其转换为 pa.uint64() 并将其编码为 dictionary

>>> table['code'].cast(pa.uint64()).dictionary_encode().type
DictionaryType(dictionary<values=uint64,ordered=0>)

这是一个独立的例子:

import pyarrow as pa

source_schema = pa.schema([
    pa.field('value',pa.int64()),pa.field('code',pa.dictionary(pa.int8(),ordered=False)),])

source_table = pa.Table.from_arrays([
    pa.array([1,2,3],pa.array([1,1000],],schema=source_schema)

destination_schema = pa.schema([
    pa.field('value',pa.dictionary(pa.int32(),])

destination_data = pa.Table.from_arrays([
    source_table['value'],source_table['code'].cast(pa.uint64()).dictionary_encode(),schema=destination_schema)

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...