如何仅使用 PyArrow 结构在 Python 中转置 PyArrow.Table 对象(最好保持连续的内存排序)?

How to transpose a PyArrow.Table object in Python using PyArrow structures only (preferably maintaining contiguous memory ordering)?

我想知道是否有一种方法可以转置 PyArrow tables 而无需例如将它们转换为 pandas 数据帧或介于两者之间的 python 个对象。

现在我正在使用类似于以下示例的东西,我认为它不是很有效(为了简洁我省略了模式):

import numpy as np
import pyarrow as pa

np.random.seed(1234)  # For reproducibility

N, M = 3, 4

arrays = [pa.array(np.random.randint(0, 4, N)) for _ in range(M)]
names = [str(x) for x in range(M)]
table = pa.Table.from_arrays(arrays, names)

print("Original:\n", table.to_pandas().values)

transposed = table.from_pandas(table.to_pandas().T)

print("\nTransposed:\n", transposed.to_pandas().values)

结果很好:

Original:
 [[3 1 0 1]
 [3 0 1 3]
 [2 0 3 1]]

Transposed:
 [[3 3 2]
 [1 0 0]
 [0 1 3]
 [1 3 1]]

在我目前正在处理的程序中,我正在使用 PyArrow 来防止我在使用 pandas 数据帧时遇到的似乎是内存泄漏的问题,我无法确定确切的问题source/cause 除了使用数据帧作为起源之外。

因此,除了效率原因,不想在这里使用 pandas 对象是首先使用 PyArrow 数据结构的原因。

有更直接的方法吗?

如果是这样,如果原始 table 也是连续的,转置后的结果是否会有连续的内存块?

此外,调用 transposed.combine_chuncks() 是否会重新排序内存以使此 table 沿柱状轴连续?

Is there a more direct way to do this?

没有。这在今天是不可能的。欢迎您提交 JIRA 票证。我找不到一个。

C++ API 具有数组生成器,这将使这非常简单,但目前没有 python 支持这些(有一个 JIRA https://issues.apache.org/jira/browse/ARROW-3917 但是即使可用,编组开销也可能成为瓶颈。

If so, would the transposed result have contiguous memory blocks if the original table is also contiguous?

Also, would calling transposed.combine_chuncks() reorder memory for this table to be contiguous along the columnar axis?

箭头数组始终沿柱状轴连续。您是在问整个 table 是否会表示为一个连续的内存区域?在那种情况下,答案是否定的。 Arrow 不会尝试将整个 table 表示为单个连续范围。

Arrow 是一种柱状格式,它不太适合这种工作量之王(table 具有更像 tensor/matrices 的统一类型)。

pandas 也可以这样说(在较小程度上),而 numpy 更适合这种类型的有效负载。因此,您可以转换为 numpy 并转置,而不是转换为 pandas 并转置。

它需要更多的代码,因为从箭头到 numpy 的转换只适用于 array/column 级别(而不是 table 级别)。参见 doc

transposed_matrix = np.array([col.to_numpy() for col in table]).T
transposed_arrays = [pa.array(col) for col in transposed_matrix]
transposed_names = [str(x) for x in range(len(transposed_arrays))]
transposed_table = table.from_arrays(transposed_arrays, names=transposed_names)