如何使用 pyarrow 15.0.0 预索引 parquet 数据集?

问题描述 投票:0回答:1

我有一个存储在 Azure 存储容器中的镶木地板数据集。 parquet 文件已分区,所有文件都具有如下路径:

exp=AB1234/
    date=2024-02-01/
        speed=100/
            load=5.1/
                data.parquet

整个数据集由约 7500 个文件和约 3 TB 组成。新数据只是偶然添加的,因此我们可以假设数据集没有改变。

通常我只需要访问一小部分数据,我在以下代码中使用 pyarrow 15.0.0 来执行此操作:

import adlfs
from azure.identity import DefaultAzureCredential
import pyarrow.parquet as pq

credentials = DefaultAzureCredential()
fs = adlfs.AzureBlobFileSystem(
    account_name=account_name,
    credential=credentials
)

filters = [('exp', 'in', ['ZY9876', 'AB1234']), ('speed', '==', '50'), ('temperature', '>', '30')]

dataset = pq.ParquetDataset(container_name,
                            memory_map=True,
                            filesystem=fs,
                            filters=filters,
                            )

df = dataset.read_pandas().to_pandas()

当我创建

ParquetDataset
的实例时,pyarrow 将首先爬行所有镶木地板文件以索引数据的所有列和值。请注意,我还将过滤器应用于文件内的列(即
('temperature', '>', '30')
)。问题是构建数据集大约需要 5-10 分钟。由于数据集不会改变,因此应该可以对所有数据建立一次索引,然后在需要数据集的一部分时加载索引。但做到这一点的最佳解决方案是什么?

我尝试使用 _metadata 和 _common_metadata 文件。这能够非常快地创建 ParquetDataset(即 3 秒),但 pyarrow 有一些注意事项,因为我需要将参数

use_legacy_dataset=True
传递给 ParquetDataset() 来读取元数据文件。这将使用旧的 Arrow Dataset API,该 API 无法过滤 parquet 文件内的列。 (除此之外,这个参数在 pyarrow 15.0.0 中也已被弃用。)因此不希望使用这种方法。

目前使用可用的 python 包对 parquet 数据集进行预索引以加快数据过滤和加载的最佳解决方案是什么?

python parquet pyarrow apache-arrow
1个回答
0
投票

数据集 api 将在过滤时使用分区。

import pyarrow.dataset as ds

expr = ds.field('exp').isin(['ZY9876', 'AB1234']) & (ds.field('speed') == 50) & (ds.field('temperature') > 30)
dataset = ds.dataset(..., partitioning='hive').filter(expr)
dataset.to_table()
© www.soinside.com 2019 - 2024. All rights reserved.