提问者:小点点

PyArrow:从分区拼花数据集中读取单个文件出乎意料地慢


我在加载. parquet文件的速度方面遇到了一些问题。然而,我不知道我做错了什么。

问题

我正在尝试从我的本地文件系统中读取单个. parque文件,该文件是火花作业的分区输出。这样在名为a=xb=y的分层目录中就有.parque文件。

为了实现这一点,我使用了read_parquet(它使用pyarrow. parque.read_table),其中我包含了过滤器kwarg。使用过滤器的运行时间比我预期的要长。

# The following runs for about 55 seconds
pd.read_parquet(<path_to_entire_dataset>, filters=[[('a', '=', 'x'), ('b', '=', 'y')]])

# The following runs for about 0.04 seconds
pd.read_parquet(<path_to_entire_dataset>/a=x/b=y/)

# The following runs for about 70 seconds
pd.read_parquet(<path_to_entire_dataset>)

通过指定过滤器读取单个镶木地板文件仅比加载整个数据集略快,我预计运行时间与文件量大致呈线性关系。

我在这里犯了什么错误?

我意识到简单地把过滤器放在路径中就可以了,但是这很快就会变得复杂,因为我想过滤的东西会/会改变。此外,我认为read_table应该能够有效地加载这些数据。

PS:整个数据集包含数百万行,我想加载的数据只有几千行。

正如0x26res所建议的,我手动定义了分区,这导致了显着的速度,但仍然没有我预期的那么快。在这种情况下,运行时间大约是5秒。

partitioning = HivePartitioning(
    pa.schema([
        pa.field('a', pa.string()),
        pa.field('b', pa.int32()),
    ])
)

pd.read_parquet(
    <path_to_entire_dataset>,
    engine='pyarrow',
    filters=[
        [
            ('a', '=', x),
            ('b', '=', y),
        ]
    ],
    partitioning=partitioning
)

共1个答案

匿名用户

给定运行时间,我怀疑箭头正在打开每个文件,然后进行过滤。

也许您可以尝试指定分区,以便箭头可以更智能:

import pyarrow as pa

partitioning = pa.dataset.HivePartitioning(
        pa.schema([
            pa.field('a', pa.string()),
            pa.field('b', pa.string())
        ])
    )

pd.read_parquet(<path_to_entire_dataset>, filters=[[('a', '=', 'x'), ('b', '=', 'y')]], partitioning=partitioning)