【问题标题】:How to change column datatype with pyarrow如何使用 pyarrow 更改列数据类型
【发布时间】:2021-05-19 06:23:51
【问题描述】:

我正在读取一组箭头文件并将它们写入 parquet 文件:

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 的范围是不够的。因此,我为 parquet 文件中的字段 code 定义了一个带有 int32 索引的架构。

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

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

【问题讨论】:

    标签: parquet pyarrow apache-arrow


    【解决方案1】:

    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, indices=int32, ordered=0>)
    

    这是一个独立的例子:

    import pyarrow as pa
    
    source_schema = pa.schema([
        pa.field('value', pa.int64()),
        pa.field('code', pa.dictionary(pa.int8(), pa.uint64(), ordered=False)),
    ])
    
    source_table = pa.Table.from_arrays([
        pa.array([1, 2, 3], pa.int64()),
        pa.array([1, 2, 1000], pa.dictionary(pa.int8(), pa.uint64(), ordered=False)),
    
    ], schema=source_schema)
    
    destination_schema = pa.schema([
        pa.field('value', pa.int64()),
        pa.field('code', pa.dictionary(pa.int32(), pa.uint64(), ordered=False)),
    ])
    
    destination_data = pa.Table.from_arrays([
        source_table['value'],
        source_table['code'].cast(pa.uint64()).dictionary_encode(),
    ], schema=destination_schema)
    

    【讨论】:

    • 我在issues.apache.org/jira/browse/ARROW-11673 报告了一个功能请求,以支持转换为不同的字典类型
    • @joris 谢谢!我正在考虑这样做,但认为这可能是一个已知问题......
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-24
    • 2019-11-08
    • 1970-01-01
    • 2020-12-12
    • 2023-03-06
    • 2018-05-28
    相关资源
    最近更新 更多