首页 > 解决方案 > 如何有效地将多个 pyarrow 表(>1,000 个表)写入分区 parquet 数据集?

问题描述

我有一些其他格式的大文件(总共大约 7,000 个,每个 4GB),我想使用 pyarrow.parquet.write_to_dataset() 将它们存储到分区(hive)目录中以进行快速查询。

目前,我正在使用以下过程遍历所有文件:

import pyarrow as pa
import pyarrow.parquet as pq

for each_file in file_list:
    ndarray_temp = reader(each_file)
    table_temp = pa.Table.from_arrays(ndarray_temp)
    pq.write_to_dataset(table_temp, root_path='xxx', partition_cols=[...])

这非常慢,因为 pq.write_to_dataset() 大约需要 27 秒才能将每个表写入目录(在 SSD 上),并且它会在每个文件夹下创建许多小 parquet 文件。

我的问题是:

  1. 有更好的方法吗?假设我有足够的内存来保存 100 个临时表,我可以一次写这 100 个表吗?

  2. 每个文件夹下数百个parquet小文件会不会影响读取和过滤性能?一张一张地写很多小表好还是一次写一张大表好?

非常感谢!

标签: pythonhiveparquetlarge-filespyarrow

解决方案


要回答您的问题:

  1. 这是一个有点自以为是的问题,它不太适合堆栈溢出。你的方法还不错,因为这种类型的工作越简单越好。如果您想通过并行处理多个文件来加速这种类型的工作流程,我建议您使用像 dask 或 luigi 这样的框架。

  2. 假设您的源文件是分区列的随机样本,那么对于您加载并保存到 parquet 的每个文件,您将在每个分区中有一个新的 parquet 文件。因此,每个分区最终可能会拥有多达 7000 个镶木地板文件。这是因为write_to_dataset每次调用时都会向每个分区添加一个新文件(而不是附加到现有文件)。这会对性能产生负面影响。如果您发现这是个问题,您可以对数据集进行“碎片整理”。为此,您将一个一个地加载分区并将它们保存到一个新的数据集中。然后,您将拥有一个每个分区只有一个文件的数据集。


推荐阅读