如何更新pyarrow表中的数据?

rap*_*l75 6 python-3.x pyarrow

我有一个 python 脚本,它使用 pyarrow 读取镶木地板文件。我正在尝试循环遍历表以更新其中的值。如果我尝试这个:

for col_name in table2.column_names:
    if col_name in my_columns:
        print('updating values in column '  + col_name)
        
        col_data = pa.Table.column(table2, col_name)
        
        row_ct = 1
        for i in col_data:
            pa.Table.column(table2, col_name)[row_ct] = change_str(pa.StringScalar.as_py(i))
            row_ct += 1
Run Code Online (Sandbox Code Playgroud)

我收到此错误:

 TypeError: 'pyarrow.lib.ChunkedArray' object does not support item assignment
Run Code Online (Sandbox Code Playgroud)

我如何更新这些值?

我尝试使用pandas,但它无法处理原始表中的空值,并且它还错误地转换了原始表中列的数据类型。pyarrow 有本地编辑数据的方法吗?

Art*_*hur 8

箭头表(和数组)是不可变的。因此您将无法就地更新您的表。

实现此目的的方法是在修改数据时创建数据副本。Arrow 支持一些基本的修改字符串的操作,但它们非常有限。

另一种选择是使用 pandas,但正如您所注意到的,从 arrow 到 pandas 并返回并不是无缝的。

让我们举个例子:

>>> table = pa.Table.from_arrays(
    [ 
        pa.array(['abc', 'def'], pa.string()),
        pa.array([1, None], pa.int32()),
    ],
    schema=pa.schema(
    [
        pa.field('str_col', pa.string()), 
        pa.field('int_col', pa.int32()), 
    ]
    )
)
>>> from_pandas = pa.Table.from_pandas(table.to_pandas())
>>> from_pandas.schema
str_col: string
int_col: double
-- schema metadata --
pandas: '{"index_columns": [{"kind": "range", "name": null, "start": 0, "' + 487
Run Code Online (Sandbox Code Playgroud)

您可以看到转换为 pandas 并返回已将 int 列的类型更改为 double。这是因为 pandas 不太支持 null int 值,因此它将 int 列转换为 double。

为了避免这个问题,我建议逐列工作,仅将字符串列转换为 pandas:

def my_func(value):
    return 'hello ' + value + '!'


columns = []
my_columns = ['str_col']
for column_name in table.column_names:
    column_data = table[column_name]
    if column_name in my_columns:
        column_data = pa.array(table['str_col'].to_pandas().apply(my_func))
    columns.append(column_data)

updated_table = pa.Table.from_arrays(
    columns, 
    schema=table.schema
)
Run Code Online (Sandbox Code Playgroud)
>>> table['str_col']
<pyarrow.lib.ChunkedArray object at 0x7f05f42b3f40>
[
  [
    "hello abc!",
    "hello def!"
  ]
]
Run Code Online (Sandbox Code Playgroud)